По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
В этом руководстве узнаем, как настроить сервер Nginx для производственной среды. Тестовый веб-сервер отличается от рабочего сервера в планах безопасности и производительности. По умолчанию, веб-сервер Ngnix готов к работе сразу после установки. Тем не менее, настройки по умолчанию недостаточны для рабочего севера. Поэтому мы сфокусируемся на настройке сервера для большей производительности в случае высокой и нормальной нагрузки, а также на настройках безопасности в целях защиты от любопытного пользователя. Если у вас не установлен веб-сервер, можете узнать, как сделать это перейдя по ссылке. Здесь показано как установить Ngnix на Unix платформы. Рекомендуется выбирать установку из исходного кода, так как обычный релиз не включает некоторые модули, используемые в этом руководстве. Настройка производительности и безопасности Nginx Требования У вас должны быть установлены нижеследующие компоненты и убедитесь, что веб-сервер запущен на системе на базе Debian, например Ubuntu. Ubuntu или любая система семейства Debian wget Vim (текстовый редактор) Также имейте ввиду, что некоторые команды из этого руководства придется запускать от имени привилегированного пользователя пользуясь командой sudo. Разбор структуры конфигурации Nginx В этом разделе рассмотрим следующие вопросы: Структура Nginx Разделы событий, HTTP и Mail Правильный синтаксис Nginx В конце раздела узнаете об структуре конфигурационного файла Nginx, роль и назначение каждого раздела и как задавать директивы внутри разделов. Весь файл конфигурации Nginx разделен на такие разделы, как event section, http section, mail section и т.д. Основной конфигурационный файл расположен по пути /etc/ngnix/ngnix.conf, а другие - /etc/nginx. Основная секция В этой секции расположены директивы, для которых нет специальных разделов. Такие директивы как user nginx, worker_processes 1, error_log /var/log/nginx/error.log warn, pid /var/run/nginx.pid могут быть расположены в этом разделе. Но некоторые из этих директив могут быть в секции event, например werker_processes. Разделы (Секции) В Nginx разделы используются для определения конфигурации разных модулей. Например, секция http section содержит настройки ngx_http_core module, секция even section определяет настройки ngx_event module, а секция mail хранит настройки модуля ngx_mail module. Список доступных разделов можно просмотреть по этой ссылке. Директивы Директивы в Nginx состоят из имени переменной и ряда аргументов. Например, директива worker_processes – имя переменной, а auto – значение: worker_processes auto; В конце каждой директивы обязательно нужно поставить точку с запятой ; Наконец, файл конфигурации Nginx должен соответствовать определенному набору правил. Ниже приведен допустимый синтаксис конфигурации Nginx: Директивы начинаются с имени переменной, а затем следуют один или несколько аргументов Директивы заканчиваются точкой с запятой ; Разделы определяются фигурными скобками {} Раздел может быть внутри другого раздела Конфигурация вне любого раздела является частью глобальной конфигурации Nginx. Строки, начинающиеся со знака #, являются комментариями. Настройка производительности Nginx В этой части мы сконфигурируем Nginx для лучшей работы как во время интенсивного трафика, так и во время пиковой нагрузки. Будут рассмотрены следующие настройки: Workers Активность Ввода/вывода диска Сетевой активности Буферов Сжатия Кеширования Времени ожидания Итак, в терминале введите следующую команду, чтобы перейти в директорию nginx и показать ее содержимое: cd nginx && ls Найдите папку conf. В этой папке и находится файл nginx.conf. Мы используем этот файл для настройки Nginx. Теперь, чтобы перейти в папку conf и открыть файл nginx.conf с помощью редактора vim, выполните следующие команды: cd conf sudo vim nginx.conf Ниже на скриншоте показан как выглядит файл nginx.conf Workers Чтобы улучшить работу веб-сервера Nginx нужно настроить должным образом так называемые воркеры. Это своего рода потоки ядра, которые управляют параллельным выполнением процессов. Настройка воркеров дает возможность эффективней обрабатывать запросы клиентов. Если все еще не закрыли vim, нажмите i чтобы перейти к режиму редактирования nginx.conf. Скопируйте и вставьте код указанный ниже в раздел events: events { worker_processes auto; worker_connections 1024; worker_rlimit_nofile 20960; multi_accept on; mutex_accept on; mutex_accept_delay 500ms; use epoll; epoll_events 512; } worker_processes: Эта директива регулирует количество воркеров в Nginx. Значение этой директивы устанавливается на auto, чтобы разрешить Nginx определять количество доступных ядер, дисков, загрузки сервера и сетевой подсистемы. Однако можно определить количество ядер, выполнив команду lscpu на терминале. worker_connections: Эта директива задает значение количества одновременных подключений, которые могут быть открыты воркером. Значение по умолчанию - 512, но здесь оно установлено 1024, что позволяет одному воркеру одновременно принимать соединение от клиента. worker_rlimit_nofile: Эта директива как-то связана с worker_connections. Для обработки большого одновременного соединения устанавливается большое значение. multi_accept: Эта директива позволяет воркеру принимать множество соединений в очереди одновременно. Очередь в этом контексте просто означает последовательность объектов данных, ожидающих обработки. mutex_accept: Эта директива отключена по умолчанию. Но поскольку мы настроили много работников в Nginx, мы должны включить его, как показано в коде выше, чтобы позволить работникам принимать новые соединения один за другим. mutex_accept_delay: Эта директива определяет время ожидания воркера перед принятием нового подключения. После включения accept_mutex воркеру назначается блокировка mutex на период, указанный в accept_mutex_delay. По истечении этого периода следующий воркер готов принять новые подключения. use: Эта директива указывает метод обработки подключения от клиента. В этом руководстве мы решили установить значение epoll, потому что мы работаем на платформой Ubuntu. Метод epoll является наиболее эффективным методом обработки для платформ Linux. epoll_events: Значение этой директивы указывает количество событий, которые Nginx передаст ядру. Чтение/запись диска В этом разделе мы настроим асинхронные операции ввода-вывода в Nginx для обеспечения эффективной передачи данных и повышения эффективности кэширования. Дисковый ввод-вывод относится к операциям записи и чтения между жестким диском и ОЗУ. Мы будем использовать функцию sendfile() внутри ядра для отправки небольших файлов. Для задания директив можно использовать http section, location section и server section. location section и server section могут быть вложены в разделе http section, чтобы сделать конфигурацию более читабельной. Скопируйте и вставьте следующий код в location section, расположенный в http section: location /pdf/ { sendfile on; aio on; } location /audio/ { directio 4m directio_alignment 512 } Sendfile: Чтобы использовать ресурсы операционной системы, установите для этой директивы значение on. Sendfile передает данные между дескрипторами файлов в пространстве ядра ОС, не отправляя их в буферы приложений. Эта директива будет использоваться для обслуживания небольших файлов. Directio: Эта директива повышает эффективность кэширования, позволяя выполнять чтение и запись непосредственно в приложение. Directio - это функция файловой системы каждой современной операционной системы. Эта директива будет использоваться для обслуживания больших файлов, например видео. Aio: Эта директива обеспечивает многопоточность для операций записи и чтения. Многопоточность - это модель выполнения, позволяющая выполнять несколько потоков отдельно друг от друга при совместном использовании ресурсов процесса хостинга. directio_alignment: В этой директиве для переноса данных назначается значение размера блока. Она касалась директивы directio. Сетевой уровень В этом разделе мы используем такие директивы, как tcp_nodelay и tcp_nopush, чтобы небольших пакеты не ждали в очереди перед отправкой. Обычно, когда пакеты передаются в "частях", они имеют тенденцию заполнять высоконагруженную сеть. Джон Нагл построил алгоритм буферизации для решения этой проблемы. Целью алгоритма буферизации Nagle является предотвращение заполнения высоконагруженной сети небольшими пакетами. Скопируйте и вставьте следующий код в раздел HTTP: http { tcp_nopush on; tcp_nodelay on; } tcp_nodelay: Эта директива по умолчанию отключена, чтобы позволить небольшим пакетам ждать указанный период времени, прежде чем они будут отправлены одновременно. Для немедленной отправки всех данных эта директива включена. tcp_nopush: Поскольку tcp_nodelay директива включена, небольшие пакеты отправляются одновременно. Однако, если вы все еще хотите использовать алгоритм буферизации Джона Нагле, мы также можем включить tcp_nopush, чтобы собрать пакеты в одну пачку и отправлять их все одновременно. Буфер Рассмотрим, как настроить буферы запросов в Nginx для эффективной обработки запросов. Буфер - это временное хранилище, где данные хранятся в течение некоторого времени и обрабатываются. Можно скопировать код указанный ниже в раздел server. server { client_body_buffer_size 8k; client_max_body_size 2m; client_body_in_single_buffer on; client_body_temp_pathtemp_files 1 2; client_header_buffer_size 1m; large_client_header_buffers 4 8k; } Важно четко понимать, функции указанных директив client_body_buffer_size: Эта директива задает размер буфера для тела запроса. Если планируется запустить веб-сервер на 64-разрядных системах, необходимо установить значение 16k. Если требуется запустить веб-сервер в 32-разрядной системе, установите значение 8k. client_max_body_size: Если вы собираетесь обрабатывать большие загрузки файлов, необходимо установить для этой директивы значение не менее 2m или более. По умолчанию установлено значение 1m. client_body_in_file_only: Если вы отключили директиву, закомментировав ее client_body_buffer_size, а директива client_body_in_file_only включена, Nginx будет сохранять буферы запросов во временный файл. Это не рекомендуется для производственной среды. client_body_in_single_buffer: Иногда не все тело запроса хранится в буфере. Остальная часть сохраняется или записывается во временный файл. Однако если предполагается сохранить или хранить все запросы в буфер запросов в одном буфере, необходимо включить эту директиву. client_header_buffer_size: Эту директиву можно использовать чтобы дать заголовков запросов доступ к буферу. Это значение можно задать равным 1m. large_client_header_buffers: Эта директива используется для задания максимального количества и размера для чтения заголовков больших запросов. Максимальное число и размер буфера можно точно установить в 4 и 8k. Сжатие Еще одним способом оптимизации работы веб-сервера является сжатие объема данных, передаваемых по сети, является. В этом разделе мы используем директивы, такие как gzip, gzip_comp_level, и gzip_min_length, чтобы сжать данные. Вставьте следующий код в раздел http, как показано ниже: http { gzip on; gzip_comp_level 2; gzip_min_length 1000; gzip_types text/xml text/css; gzip_http_version 1.1; gzip_vary on; gzip_disable "MSIE [4-6] ."; } gzip: Если требуется включить сжатие ответа, установите значение этой директивы в on. По умолчанию он отключен. gzip_comp_level: Эту директиву можно использовать для установки степени сжатия ответа. Чтобы не тратить ресурсы ЦП, не нужно устанавливать слишком высокий уровень сжатия. По шкале от 1 до 9 лучше установить уровень сжатия 2 или 3. gzip_min_length: Устанавливает минимальную длину ответа, который будет сжиматься методом gzip. Длина определяется только из поля content-length заголовка ответа. Можно установить значение более 20 байт. gzip_types: Эта директива разрешает сжатие ответа методом gzip для указанных MIME-типов. По умолчанию, тип text/html всегда сжимается. Можно добавить другой тип, например, text/css, как показано в коде выше gzip_http_version: Эта директива позволяет выбрать минимальную HTTP-версию запроса, необходимую для сжатия ответа. Можно использовать значение по умолчанию 1.1. gzip_vary: Разрешает или запрещает выдавать в ответе поле заголовка Vary: Accept Encoding, если директива gzip включена. gzip_disable: Некоторые браузеры, такие как Internet Explorer 6, не поддерживают сжатие gzip. Эта директива использует поле User-Agent заголовка для отключения сжатия методом gzip для определенных браузеров. Кеширование Используйте функции кэширования, чтобы сократить количество обращений для многократной загрузки одних и тех же данных. Nginx предоставляет функции кэширования метаданных статического содержимого через директиву open_file_cache. Эту директиву можно поместить в разделы server, location и http: http { open_file_cache max=1,000 inactive=30s; open_file_cache_valid 30s; open_file_cache_min_uses 4; open_file_cache_errors on; } open_file_cache: Эта директива по умолчанию отключена. Включите его, если требуется внедрить кэширование в Nginx. В нем могут храниться дескрипторы открытых файлов, информация об их размерах и времени модификации, информация о существовании каталогов, информация об ошибках поиска файла — “нет файла”, “нет прав на чтение” open_file_cache_valid: Эта директива определяет время, через которое следует проверять актуальность информации об элементе в open_file_cache. open_file_cache_min_uses: Задаёт минимальное число обращений к файлу в течение времени, заданного параметром inactive директивы open_file_cache, необходимых для того, чтобы дескриптор файла оставался открытым в кэше. open_file_cache_errors: Эту директиву можно использовать, чтобы разрешить Nginx кэшировать ошибки, такие как “нет файла”, “нет прав на чтение” при доступе к файлам. Таким образом, каждый раз, когда к ресурсу обращается пользователь, не имеющий на это права, Nginx отображает тот же самый отчет об ошибке «в доступе отказано» Время ожидания Настройте время ожидания, используя директивы, такие как keepalive_timeout и keepalive_requests, чтобы предотвратить растрачивание ресурсов при длительном ожидании подключений. В разделе HTTP скопируйте и вставьте следующий код: http { keepalive_timeout 30s; keepalive_requests 30; send_timeout 30s; } keepalive_timeout: Сохраняйте связь в течение 30 секунд. Значение по умолчанию - 75 секунд. keepalive_requests: Настройка количества запросов для поддержания активности в течение определенного времени. Количество запросов можно задать равным 20 или 30. keepalive_disable: если вы хотите отключить поддержку keepalive для определенной группы браузеров, используйте эту директиву. send_timeout: Установка времени ожадания для передачи данных клиенту. Настройки безопасности Nginx В этой части рассматриваются только способы настройки безопасности самого Nginx, а не веб-приложения. Мы не будем разбирать такие методы веб-атаки, как инъекция SQL и так далее. Здесь мы рассмотрим настройки следующих параметров: Ограничение доступа к файлам и каталогам Настройка журналов для мониторинга подозрительных действий Защиту от DDoS атак Отключение вывода списка файлов и директорий Ограничение доступа к файлам и каталогам Давайте рассмотрим как можно ограничить доступ к важным и чувствительным файлам системы с помощью следующих методов. Использование HTTP Аутентификации С ее помощью мы можем ограничить доступ к конфиденциальным файлам или разделам системы, не предназначенных для публичного доступа, запросив аутентификацию у пользователей или даже администраторов. Выполните следующую команду, чтобы установить утилиту создания файлов паролей, если она не установлена. apt-get install -y apache-utils Далее создайте файл паролей и пользователя с помощью утилиты htpasswd. htpasswd входит в набор утилит apache2-utils. sudo htpasswd -c /etc/apache2/ .htpasswd mike Проверить результат работы можно командой: cat etc/apache2/ .htpasswd Скопируйте и вставьте следующий код в разделе location: location /admin { basic_auth "Admin Area"; auth_basic_user_file /etc/apache2/ .htpasswd; } Используя директиву Allow В дополнение к директиве basic_auth мы можем использовать директиву allow для ограничения доступа к указанным каталогам. Чтобы разрешить доступ как конкретным каталогам только с указанных адресов вставьте нижеследующий код в раздел location: location /admin { allow 192.168.34.12; allow 192.168.12.34; } Настройка журналирования подозрительных действий В этом разделе настроим error и access логи, чтобы вести мониторинг запросов. Их можно использовать для определения кто заходил систему в указанный период времени или какой пользователь открывал конкретный файл и т.д. error_log: Позволяет настроить запись событий в определенный файл, например syslog или stderr. Можно также указать уровень журналирования, которые требуется записывать. access_log: Позволяет регистрировать запросы пользователей в файле access.log Для этого в разделе http введите следующие изменения: http { access_log logs/access.log combined; error_log logs/warn.log warn; } Предотвращение DDoS атак DDoS атаки один из самых легкореализуемых и потому часто применяемых видов атак. Защитить свой веб-сервер от атак такого вида можно поменяв следующие настройки. Ограничение запросов пользователей Для ограничения числа запросов от пользователей можно использовать директивы limit_req_zone и limit_req. Следующий код нужно добавить в раздел location, который вложен в раздел server limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m; server { location /admin.html { limit_req zone=one; } } Ограничение на число подключений Директивы limit_conn и limit_conn_zone можно использовать для ограничения числа подключение к конкретным зонам. Например, код указанный ниже ограничивает число подключений десятью. Код должен располагаться в разделе location раздела server server { location /products/ { limit_conn addr 10; } } Разрыв медленных соединений Директива как client_body_timeout задаёт таймаут при чтении тела запроса клиента. Таймаут устанавливается не на всю передачу тела запроса, а только между двумя последовательными операциями чтения. Если по истечении этого времени клиент ничего не передаст, обработка запроса прекращается с ошибкой 408 (Request Time-out). А client_header_timeout задаёт таймаут при чтении заголовка запроса клиента. Если по истечении этого времени клиент не передаст полностью заголовок, обработка запроса прекращается с ошибкой 408 (Request Time-out). Добавьте следующее в раздел server. server { client_body_timeout 5s; client_header_timeout 5s; } Отключение вывода списка директорий Чтобы отключить вывод директорий на странице можно использовать директиву auto_index. Она располагается в разделе location, а значение должно быть установлено в off. location / { auto_index off; } Заключение Итак, в этом руководстве показали, как можно настроить веб-сервер Nginx для более безопасной и оптимальной работы. На этом, конечно, работа не заканчивается. Если на Nginx крутится какое-то приложение с доступом в Интернет, то можно прибегнуть к облачным решениям защиты и оптимизации.
img
Привет, друг! В марте 2017 года на сайте разработчика FreePBX Distro появился новый дистрибутив, который включает в себя FreePBX 14 версии, Linux 7.3 и само ядро обработки телефонных вызовов – Asterisk (11, 13 и 14 версии). Отметим, что на момент написания статьи релиз проходит полномасштабное тестирование и доступен в формате «релиз - кандидата», или просто RC (Release Candidate). В статье рассмотрим процесс установки дистрибутива RC 1 SNG7-FPBX-64bit-1703-1 и проведем беглый обзор новых «фишек». Установка Установку мы будем производить на виртуальной машине в среде виртуализации Hyper-V. После загрузки .iso дистрибутива с сайта разработчика, сравниваем его MD5 - сумму и подключаем его к виртуальному приводу и включаем виртуальную машину: Выбираем рекомендуемую опцию инсталляции и нажимаем Enter: Выбираем опцию вывод детализации информации об установке через VGA и нажимаем Enter: Оставляем селектор на стандартной установке и нажимаем Enter: Начинается процесс установки, который занимает примерно 10-20 минут. По окончанию установки мы увидим соответствующее сообщение. Нажимаем Reboot: Готово. Переходим к изучению нового интерфейса. Новый интерфейс FreePBX 14 Из нововведений сразу в глаза бросается виджет Live Network Usage, который показывает загрузку виду Tx/Rx (передача/прием) на сетевом интерфейсе: Пробежимся по вкладке Admin. Мы нашли дополнительный раздел Updates, в котором теперь можно планировать автоматическое обновление системы и модулей: Во вкладке Applications появился модуль Calendar, который позволяет производить интеграцию с календарями (Outlook, iCal, CalDAV и обычный локальный календарь): Важнейшей особенностью нового интерфейса является UCP (User Control Panel) 14 версии, в котором полностью переделана графическая компонента, визуализация информации, добавлена гибкая система настройки «дашбордов» и настройки виджетов: Мы продолжим следить за новым релизом и держать вас в курсе :)
img
REST API – один из самых распространенных типов доступных веб-сервисов, но проектировать их сложно. Они позволяют разным клиентам, включая браузер, настольные приложения, мобильные приложения и практически любое устройство с подключением к Интернету, взаимодействовать с сервером. Именно поэтому очень важно правильно проектировать REST API, чтобы в будущем не было проблем. Создание API с нуля может оказать непосильной задачей из-за большого количества вещей, которые необходимо учесть – от базовой безопасности до использования правильных методов HTTP, реализации аутентификации, определения того, какие запросы и ответы среди многих других принимаются и возвращаются. В этой статье я очень постарался сжать материал в 15 пунктов с важными рекомендациями, которые позволят создать хороший API. Все рекомендации никак не зависят от языка, поэтому потенциально применимы к любой платформе или технологии. 1. Обязательно используйте имена существительные в названиях путях к конечным точкам Вам всегда следует использовать имена существительные, которые обозначают объект, который вы извлекаете или которым вы манипулируете. В качестве имени пути всегда предпочтительнее использовать множественное число. Избегайте использования глаголов в названиях путях к конечным точкам, потому что наш метод HTTP-запроса уже является глаголом и по сути не добавляет никакой новой информации. Действие должно быть произведено с помощью методов HTTP-запроса. Наиболее распространенными являются методы GET, POST, PATCH, PUT и DELETE. GET извлекает ресурсы POST отправляет новые данные на сервер PUT/PATCH модифицируют уже существующие данные DELETE удаляет данные Глаголы сопоставляются с функциями CRUD (Create, read, update и delete). Помня об этих принципах, мы должны создавать маршруты типа GET /books для получения списка книг, а не GET /get-books или GET /book. Аналогично, POST /books - для добавления новой книги, PUT /books/:id - для модификации полных данных книги с заданным идентификатором (id), а PATCH /books/:id обновляет частичные изменения в книге. И наконец, DELETE /books/:id предназначен для удаления существующей книги в заданным идентификатором. 2. JSON как основной формат отправки и получения данных Несколько лет назад прием и ответы на запросы API выполнялись в основном в XML. Но сейчас «стандартным» форматом для отправки и получения данных API в большинстве приложений стал JSON. Поэтому наш второй пункт рекомендует убедиться, что конечные точки возвращают формат данных JSON в качестве ответа, а также при приеме информации через полезную нагрузку HTTP-сообщений. Несмотря на то, что FormData хорошо подходит для отправки данных от клиента, особенно если нам нужно отправлять файлы, они не очень подходят для текста и чисел. Нам не нужны FormData для их передачи, так как в большинстве фреймворков можно передавать JSON непосредственно на стороне клиента. При получении данных от клиента нам необходимо убедиться, что клиент правильно интерпретирует данные JSON, и для этого при выполнении запроса в заголовке ответа Content-Type должен быть установлен на application/json. Стоит еще раз упомянуть исключение, когда мы пытаемся отправлять и получать файлы между клиентом и сервером. В этом конкретном случае нам необходимо обрабатывать файл ответа и отправлять FormData с клиента на сервер. 3. Используйте коды состояний HTTP Коды состояний HTTP всегда полезно использовать для того, чтобы указать на выполнение или невыполнение запроса. Не используйте слишком много кодов состояний и всегда используйте одни и те же коды для одних и тех же результатов в API. Вот некоторые примеры: 200 – общее выполнение 201 – успешное создание 400 – неверные запросы от клиента, такие как неверные параметры 401 – несанкционированные запросы 403 – отсутствие прав доступа к ресурсам 404 – отсутствуют ресурсы 429 – слишком много запросов 5хх – внутренние ошибки (их следует избегать насколько это возможно) В зависимости от ситуаций их может быть и больше, но ограничение количества кодов состояний помогает клиенту использовать более предсказуемый API. 4. Возвращайте стандартизированные сообщения Помимо использования кодов состояния HTTP, которые указывают на результат запроса, всегда используйте стандартизированные ответы для аналогичных конечных точек. Пользователи могут всегда рассчитывать на одинаковую структуру и действовать соответственно. Это также относится к статусу, указывающему на выполнение запроса, и сообщениях об ошибках. В случае выборки коллекций придерживайтесь определенного формата, независимо от того, включает ли тело ответа массив данных, подобный этому: [ { bookId: 1, name: "The Republic" }, { bookId: 2, name: "Animal Farm" } ] или вот такой комбинированный ответ: { "data": [ { "bookId": 1, "name": "The Republic" }, { "bookId": 2, "name": "Animal Farm" } ], "totalDocs": 200, "nextPageId": 3 } Здесь рекомендация заключается в том, чтобы быть последовательным независимо от того, какой подход вы выберете для этого. Аналогичное поведение должно быть реализовано при извлечении объекта, а также при создании и модификации ресурсов, которым обычно рекомендуется возвращать последний экземпляр объекта. // Ответ после успешного вызова POST /books { "bookId": 3, "name": "Brave New World" } Хоть это и никак не навредит, но все же излишнем будет включать универсальное сообщение, например, «Книга успешно создана», так как это уже следует из кода состояния HTTP. И последнее, но не менее важное: при наличии стандартного формата ответа коды ошибок также важны (и даже более важные). Это сообщение должно включать информацию, которую клиент может использовать для представления ошибок конечному пользователю, а соответственно, это должно быть не общее предупреждение, такое как «то-то пошло не так», которого следует избегать, насколько это возможно. Вот пример: { "code": "book/not_found", "message": "A book with the ID 6 could not be found" } Опять же, нет необходимости включать код состояния в содержимое ответа, но полезно определить набор кодов ошибок, таких как book/not_found, чтобы пользователь мог сопоставить их с разными строками и создать свое собственное сообщение об ошибке для конечного пользователя. В частности, для сред разработки или промежуточных сред может показаться правильным также включить стек ошибок в ответ с целью помочь в отладке ошибок. Но не включайте те, что находятся в промышленной эксплуатации, так как это создаст угрозу безопасности, раскрывая незапланированную информацию. 5. Используйте разбиение на страницы, фильтрацию и сортировку при выборе коллекций записей Как только будет создана конечная точка, которая возвращает список элементов, необходимо будет установить разбиение на страницы. Обычно коллекции со временем растут, поэтому важно всегда следить за тем, чтобы возвращалось ограниченное и контролируемое количество элементов. Справедливо будет позволить пользователям API выбирать, сколько объектов получить, но всегда полезно заранее определить число и установить для него максимум. Основная причина, почему нужно это сделать, заключается в том, что для возврата огромного массива данных потребуется очень много времени и большая пропускная способность. Для реализации нумерации страниц есть два хорошо известных способа: skip/limit или keyset. Первый вариант обеспечивает более удобный для пользователя способ извлечения данных, но обычно он менее эффективен, так как базы данных сканируют множество документов для извлечения нужных записей. Мне больше нравится второй вариант. Разделения на страницы с помощью keyset получает идентификатор (id) в качестве ссылки для «вырезания» коллекции или таблицы с условием без сканирования записей. Также API должны предоставлять фильтры и возможности сортировки, которые упрощают способы получения данных. Частью решения повышения производительности являются индексные базы данных, которые позволяют максимизировать производительность при помощи шаблонов доступа, которые применяются с фильтрами и параметрами сортировки. При проектировании API эти свойства разбиения на страницы, фильтрации и сортировки определяются как параметры запроса в URL-адресе. Например, если вы хотим получить информацию о первых 10 книгах, принадлежащих к категории «роман», то наша конечная точка будет выглядеть вот так: GET /books?limit=10&category=romance 6. PATCH вместо PUT Маловероятно, что необходимо будет сразу полностью обновить всю запись, обычно есть конфиденциальные или полные записи, которые следует уберечь от манипуляций пользователя. Именно поэтому для выполнения частичных обновлений ресурса следует использовать PATCH, а вот PUT полностью меняет существующий ресурс. Они оба должны использовать тело запроса для передачи информации, подлежащей модификации. Разница лишь в том, что для PATCH это поля, а для запроса PUT – полный объект. Тем не менее, стоит отметить, что ничто не мешает нам использовать PUT для частичной модификации, нет никаких «ограничений на передачу по сети», которые бы это подтверждали. Это просто факт, которого стоит придерживаться. 7. Предоставьте более подробные ответы Шаблоны доступа являются ключевыми при создании доступных ресурсов API и возвращаемых данных. Когда система растет, то и свойства записи также растут, но не всегда все эти свойства нужны клиентам для работы. Именно в таких ситуациях становится полезным предоставление возможности возвращать сокращенные или полные ответы для одной и той же конечной точки. Если пользователю нужны только некоторые поля, то упрощенный ответ помогает снизить расход трафика и потенциально сложность получения других вычисляемых полей. Простой способ реализовать – предоставить дополнительный параметр запроса, чтобы включить или отключить предоставление более подробного ответа. GET /books/:id { "bookId": 1, "name": "The Republic" }GET /books/:id?extended=true { "bookId": 1, "name": "The Republic" "tags": ["philosophy", "history", "Greece"], "author": { "id": 1, "name": "Plato" } } 8. Обязанность конечной точки Принцип единственной обязанности фокусируется на концепции удержания функции, метода или класса на одной обязанности, которую они выполняют хорошо. Мы можем сказать, что это наш API - хороший API, если он выполняет одну конкретную вещь и никогда не меняется. Это помогает пользователям лучше понять наш API и сделать его более предсказуемым, что облегчит общую интеграцию. Лучше всего расширить список доступных конечных точек, а не создавать очень сложные конечные точки, которые пытаются решить множество задач одновременно. 9. Предоставьте полную документацию по API Пользователи вашего API должны понимать, как использовать доступные конечные точки и чего ожидать. Это возможно только при наличии хорошей и подробной документации. Обратите внимание на следующие аспекты, чтобы ваша документация была полной. Доступные конечные точки с описанием их назначения Права доступа, необходимые для выполнения конечной точки Примеры вызовов и ответов Сообщения о предполагаемых ошибках Немаловажным является постоянное обновление документации после внесения изменений и дополнений в систему. Лучший способ для этого – сделать документацию по API неотъемлемой частью разработки. Двумя хорошо известными инструментами в данном вопросе являются Swagger и Postman – они доступны для большинства сред разработки API. 10. Используйте SSL для обеспечения безопасности и настройте CORS Безопасность – еще одно очень важной свойство, которым должен обладать наш API. Настройка SSL путем установки действительного сертификата на сервер обеспечит безопасную связь с пользователями и предотвратит некоторые виды потенциальных атак. CORS (Cross-origin resource sharing – Обмен ресурсами с запросом происхождения) – это функция безопасности браузера, которая ограничивает HTTP-запросы из различных источников, которые инициируются сценариями, запущенными в браузере. Если ресурсы вашего REST API получают непростые HTTP-запросы из разных источников, то вам нужно включить поддержку CORS для того, чтобы пользователи работали соответствующим образом. Протокол CORS требует, чтобы браузер отправил предварительный запрос на сервер и дождался утверждения (или запрос учетных данных) с сервера перед отправкой фактического запроса. Запрос предварительной проверки отображается в API как HTTP-запрос, использующий метод OPTIONS (среди других заголовков). Значит, для поддержки CORS в ресурсе REST API необходимо реализовать метод OPTIONS, который будет отвечать на предварительный запрос, по крайней мере, со следующими заголовками ответа, предусмотренными стандартом Fetch: Access-Control-Allow-Methods Access-Control-Allow-Headers Access-Control-Allow-Origin Какие значения назначать этим ключам, зависит от того, настолько открытым и гибким должен быть наш API. Мы можем назначить определённые методы и известные источники или использовать специальные символы, чтобы иметь открытые ограничения CORS. 11. Управление версиями API В процессе разработки конечные точки начинают меняться и перестраиваться. Но мы должны, насколько это возможно, избегать внезапного изменения конечных точек для пользователя. Рекомендуется рассматривать API как ресурс с обратной совместимость, в котором новые и обновленные конечные точки должны быть доступны, но не должны влиять на предыдущие стандарты. Вот где управление версиями API приходит на помощь – когда клиенты должны иметь возможность выбирать, к какой версии подключаться. Есть несколько способов описать управление версиями API: Добавление нового заголовка x-version=v2 Наличие параметра запроса ?apiVersion=2 Версия как часть URL: /v2/books/:id 12. Кэшируйте данные для повышения производительности Чтобы повысить производительность нашего API, полезно следить за данными, которые редко меняются и к которым часто обращаются. Для таких данных мы можем рассмотреть возможность использования базы данных в памяти или кэш-памяти, которая избавит от доступа к основной базе данных. Главная проблема здесь заключается в том, что данные могут устареть, поэтому следует решить вопрос с внедрением последней версии. Использование кэшированных данных будет полезным для пользователей для загрузки конфигураций и каталогов информации, которые не предназначены для постоянного изменения в течение долгого времени. При использовании кэширования не забудьте включить Cache-Control в заголовки. Это поможет пользователям эффективно использовать систему кэширования. 13. Используйте даты в формате UTC Сложно представить системы, которые в какой-то момент перестает работать из-за дат. На уровне данных важно быть логичным в том, как даты отображаются на клиентских приложениях. ISO 8601 – это международный стандартный формат данных для даты и времени. Данные должны быть в формате Z или UTC, для которых пользователи могут могли бы выбрать часовой пояс в случае, если такая дата должны отображаться при любых условиях. Вот пример того, как должны выглядеть даты: { "createdAt": "2022-03-08T19:15:08Z" } 14. Конечная точка проверки работоспособности Может произойти ситуация, когда наш API перестанет работать, и для его запуска потребуется время. При таких обстоятельствах клиенты хотят знать, что службы недоступны, и быть в курсе ситуации. Для этого предоставьте конечную точку (например, GET /health), которая бы определяла работоспособность API. Эта конечная точка может вызываться и другими приложениями, такими как балансировщики нагрузки. Можно продвинуться еще дальне и сообщать о периодах технического обслуживания или работоспособности частей API. 15. Разрешите аутентификацию по ключу API Аутентификация с помощью ключей API даст возможность сторонним приложениям легко создавать интеграцию с нашим API. Эти ключи API следует передавать с помощью пользовательского заголовка HTTP (например, Api-Key или X-Api-Key). Ключи должны иметь дату окончания срока действия, и должна быть возможность их отозвать с целью признания недействительными по соображениям безопасности.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59