Понимание и использование RESTful API
Yi Sun
December 2, 2022
В эпоху Интернета вещей существует множество различных API, и важно их стандартизировать. RESTful API — это один из самых популярных архитектурных стилей API, который помогает разделить клиентскую и серверную части, позволяя фронтенду и бэкенду развиваться независимо, что повышает эффективность. Его безсостоятельный характер делает приложение более масштабируемым и упрощает реализацию политик кэширования для улучшения пользовательского опыта и производительности. В этой статье мы расскажем, что такое RESTful API и как его использовать.
Что такое API
Прежде чем говорить о том, что такое API, давайте обсудим, как мы передаем информацию в повседневной жизни.
Когда вы отдаете деньги продавцу в магазине и говорите, что хотите купить батарейки, продавец принимает деньги, находит батарейки на полке и передает их вам. Транзакция по покупке батареек успешно завершена.
Компьютерное программное обеспечение, с другой стороны, выполняет это через API. Начнем с определения из Википедии:
API (Application Programming Interface) — это способ взаимодействия двух или более компьютерных программ. Это тип программного интерфейса, предоставляющего услуги другим частям программного обеспечения.
Программа A делает запрос к программе B через API, и программа B возвращает ответ A через API после запроса своих ресурсов.
Программа A, делающая запрос к программе B через API, похожа на то, как вы говорите продавцу, что вам нужны батарейки, а программа B, возвращающая данные программе A, похожа на то, как продавец находит батарейки и передает их вам.
Этот процесс не требует, чтобы программа B знала, зачем программе A нужны данные, так же как продавец не спросит вас, зачем вы купили батарейки. Программа A также не должна знать, как программа B нашла данные, так же как вы не спросите продавца, где были куплены батарейки. Каждая программа передает информацию друг другу через API, и каждая выполняет свою задачу, делая мир программирования упорядоченным и надежным.
Что такое RESTful API
Рой Филдинг определил REST (Representational State Transfer) в своей диссертации 2000 года "Архитектурные стили и проектирование веб-ориентированной программной архитектуры", и архитектурный стиль REST определяет шесть руководящих ограничений. Система, которая соответствует некоторым или всем этим ограничениям, называется RESTful.
(Источник: Seobility)
Ограничения RESTful API
| Ограничения | Детали | Преимущества |
|---|---|---|
| Архитектура клиент-сервер | Улучшает переносимость пользовательского интерфейса на нескольких платформах, разделяя вопросы пользовательского интерфейса и хранения данных, а также улучшает масштабируемость за счет упрощения серверных компонентов. | 1. Разделение клиентской и серверной частей. 2. Улучшение переносимости пользовательских платформ на разных платформах. 3. Улучшение масштабируемости серверной части. |
| Безсостоятельность | Каждый запрос от клиента к серверу должен содержать всю информацию, необходимую для выполнения запроса, и не должен использовать какой-либо контекст, хранящийся на сервере, а состояние сессии полностью хранится на клиенте. | 1. Легко масштабировать, нет зависимостей от сессий, и любой сервер может обработать любой запрос. 2. Упрощает кэширование для повышения производительности программы. |
| Кэшируемость | Требует, чтобы данные в запросе или ответе были явно или неявно помечены как кэшируемые или не кэшируемые. Если ответ кэшируемый, то клиентскому кэшу предоставляется право повторно использовать эти данные для последующих эквивалентных запросов. | 1. Снижение пропускной способности. 2. Снижение задержки. 3. Снижение нагрузки на сервер. 4. Скрытие состояния сети. |
| Многоуровневая система | Ограниченное поведение компонентов позволяет архитектуре состоять из уровней, так что каждый компонент не может "видеть" за пределы ближайшего уровня, с которым он взаимодействует. Ограничивая знания системы одним уровнем, снижается сложность всей системы и повышается независимость на нижних уровнях. | 1. Снижение сложности всей системы. 2. Повышение независимости на нижних уровнях. 3. Легко реализовать балансировку нагрузки. 4. Бизнес-логика и политики безопасности могут быть разделены. |
| Код по требованию (опционально) | Позволяет расширять функциональность клиента за счет загрузки и выполнения кода в виде апплетов или скриптов. | 1. Повышение масштабируемости системы. |
| Единый интерфейс | Содержит четыре основных пункта: 1. Идентификация ресурсов в запросах. Клиенты могут идентифицировать ресурс по URI, содержащемуся в запросе, что разделяет ресурсы на стороне сервера и ресурсы, запрашиваемые клиентом. 2. Управление ресурсами через представления. Когда клиент имеет представление ресурса, например URI, то у него достаточно информации для изменения или удаления ресурса. 3. Самоописательные сообщения. Каждое сообщение содержит достаточно информации, чтобы клиент мог понять, что делать с этим сообщением. 4. Гипермедиа как движок состояния приложения (HATEOAS). Клиенту не требуется дополнительное кодирование, чтобы сделать все ресурсы доступными пользователю через ссылки на ресурсы, возвращаемые сервером. | 1. Упрощение общей архитектуры системы. 2. Повышение видимости взаимодействий. |
Лучшие практики RESTful API
Акцент на единых интерфейсах между компонентами — это ключевая особенность, которая отличает архитектурный стиль REST от других веб-ориентированных стилей. На основе этой особенности здесь собраны лучшие практики, которые помогут вам лучше проектировать свои API.
Избегайте глаголов в названиях путей
Используйте HTTP-методы для выражения действий с ресурсами, вместо того чтобы определять глаголы действий в путях.
// Хорошо curl -X GET http://httpbin.org/orders // Плохо curl -X GET "http://httpbin.org/getOrders"
- Получение информации о ресурсе по указанному URI с помощью GET
// Получение всей информации о заказах в системе curl -X GET http://httpbin.org/orders // Получение деталей заказа с номером 1 curl -X GET http://httpbin.org/orders/1
- Создание ресурса по указанному URI с помощью POST
// Создание ресурса с именем order curl -X POST http://httpbin.org/orders \ -d '{"name": "awesome", region: "A"}' \
- Создание или полная замена ресурсов по указанному URI с помощью PUT
// Замена данных для заказа с id 1 curl -X PUT http://httpbin.org/orders/1 \ -d '{"name": "new awesome", region: "B"}' \
- PATCH выполняет частичное обновление ресурса
// Изменение поля region для заказа с id 1, оставляя остальные данные неизменными curl -X PATCH http://httpbin.org/orders/1 \ -d '{region: "B"}' \
- Удаление ресурса по указанному URI с помощью DELETE
// Удаление заказа с id 1 curl -X DELETE http://httpbin.org/orders/1
Используйте множественное число в URI
Если вы хотите использовать единственное число для обозначения доступа к определенному типу ресурса:
curl -X GET "http://httpbin.org/order"
Использование единственного числа может ввести пользователя в заблуждение, что в системе есть только один заказ, но использование множественного числа делает понимание более плавным.
curl -X GET "http://httpbin.org/orders"
Правильное использование HTTP-статусов
Стандарт HTTP определяет статусные коды, которые можно разделить на следующие категории:
| Статусные коды | Значение |
|---|---|
| 2xx | Успех, операция успешно получена и обработана |
| 3xx | Перенаправление, требуется дополнительное действие для завершения запроса |
| 4xx | Ошибка клиента, запрос содержит синтаксическую ошибку или не может быть выполнен |
| 5xx | Ошибка сервера, произошла ошибка при обработке запроса сервером |
Использование стандартных статусных кодов позволяет разработчикам сразу идентифицировать проблемы и сокращает время поиска различных типов ошибок.
Управление версиями
По мере изменения бизнес-требований API, которые уже используются, скорее всего, потребуется адаптировать. Если наши API используются третьими сторонами, очевидно, невозможно заставить каждого клиента изменяться в соответствии с изменениями наших API, поэтому необходимо ввести концепцию управления версиями API, что гарантирует нормальное использование исторических API и итерацию новых API для удовлетворения новых бизнес-требований.
Распространенные способы управления версиями:
- Управление версиями через пути в запросах
// Запрос API версии v1 curl http://httpbin.org/v1/orders // Запрос API версии v2 curl http://httpbin.org/v2/orders
- Управление версиями через параметры запроса
// Запрос API версии v1 curl http://httpbin.org/orders?version=v1 // Запрос API версии v2 curl http://httpbin.org/v2/orders?version=v2
- Управление версиями через заголовки
// Запрос API версии v1 curl http://httpbin.org/orders -H "custom-version: v1" // Запрос API версии v2 curl http://httpbin.org/orders -H "custom-version: v2"
Как APISIX улучшает RESTful API
Apache APISIX — это динамический, реального времени, высокопроизводительный API-шлюз. Он может работать перед любым RESTful API-сервисом и использовать плагины для добавления новых сервисов и расширения его функциональности, что соответствует определению RESTful Многоуровневая система. Кроме того, для некоторых исторических сервисов, которые не следуют определению RESTful API, APISIX также может помочь вам преобразовать ваш интерфейс без изменения исходного бизнес-кода, чтобы ваш интерфейс соответствовал ограничению REST Единый интерфейс, делая ваш API более соответствующим спецификации RESTful API.
Многоуровневая система: Поддержка разделения бизнес-логики и логики безопасности
Вы можете сосредоточиться на реализации бизнес-логики, а логику безопасности интерфейса можно оставить плагинам аутентификации APISIX, например key-auth. APISIX поддерживает множество плагинов аутентификации, давайте рассмотрим openid-connect в качестве примера, как показано на следующем рисунке:
Мы видим, что использование APISIX (API-шлюза) для добавления уровня логики аутентификации перед нашим бизнес-сервером может служить защитой вышестоящих сервисов, и этот архитектурный паттерн может хорошо разделить вашу бизнес-логику и логику безопасности.
Многоуровневая система: Поддержка нескольких протоколов балансировки нагрузки
APISIX, как API-шлюз, может быть настроен между клиентской и серверной сторонами для выполнения различных требований балансировки нагрузки. Вы даже можете настроить собственную логику балансировки нагрузки.
Поддерживаемые алгоритмы балансировки нагрузки:
roundrobin: Циклическая балансировка с весами.chash: Консистентный хэш.ewma: Выбор узла с минимальной задержкой. Подробнее см. EWMA Chart.least_conn: Выбор узла с наименьшим значением(active_conn + 1) / weight. Здесь активное соединение — это соединение, используемое запросом, и оно аналогично концепции в Nginx.- Пользовательский балансировщик нагрузки, загружаемый через
require("apisix.balancer.your_balancer")
Единый интерфейс: Сделайте исторические API более RESTful
Для исторических API, которые существуют уже давно и не следуют рекомендациям RESTful API, вы можете повторно инкапсулировать новый API через APISIX, чтобы удовлетворить различные бизнес-сценарии без изменения исходной логики API.
- Используйте proxy-rewrite для перезаписи клиентских запросов
Как упоминалось выше, мы не должны использовать глаголы в наших путях.
Например, если исторический API имеет интерфейс /getOrder, мы можем проксировать запрос API к историческому API через плагин proxy-rewrite.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "methods": ["GET"], "uri": "/orders", "plugins": { "proxy-rewrite": { "uri": "/getOrder", "scheme": "http", } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:80": 1 } } }'
Вы также можете использовать плагин для операций управления версиями API.
- Используйте плагин response-rewrite для перезаписи ответов сервера
Когда наш исторический API имеет нестандартные коды статусов ответов, мы можем использовать response-rewrite для проксирования ответа и изменения кода статуса ответа.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "methods": ["GET"], "uri": "/orders", "plugins": { "response-rewrite": { "status_code": 201, "body": "{\"code\":\"ok\",\"message\":\"new json body\"}", "vars":[ [ "status","==",200 ] ] } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:80": 1 } } }'
Приведенный выше пример представляет запрос на изменение статуса 200 на 201 в API, запрашивающем путь /orders.
Поскольку APISIX поддерживает очень богатые плагины, я с нетерпением жду, когда вы исследуете больше способов их использования.
Заключение
В этой статье рассказывается, что такое API, что такое RESTful API и его лучшие практики. Кроме того, в статье также рассказывается, как разделить бизнес-логику и логику безопасности через APISIX, и как использовать APISIX для того, чтобы сделать исторические API-сервисы более RESTful без изменения исходного бизнес-кода. Надеюсь, эта статья поможет вам лучше понять RESTful API.