Цепочка API-запросов с использованием API Gateway
May 23, 2023
По мере увеличения количества API, которые необходимо интегрировать, управление сложностью взаимодействий между API становится все более сложной задачей. Используя API Gateway, мы можем создать последовательность вызовов API, что позволяет разбить рабочие процессы API на более мелкие и управляемые шаги. Например, на сайте интернет-магазина, когда клиент ищет товар, платформа может отправить запрос к API поиска товаров, а затем запрос к API деталей товара для получения дополнительной информации о товарах. В этой статье мы создадим пользовательский плагин для Apache APISIX API Gateway, который будет обрабатывать клиентские запросы, которые должны вызываться последовательно.
Цели обучения
В этой статье вы узнаете следующее:
- Что такое цепочки запросов API?
- Пример последовательных вызовов API.
- Как создать пользовательский плагин pipeline-request для Apache APISIX.
- Демонстрация плагина pipeline-request.

Что такое цепочка запросов API и зачем она нужна?
Цепочка запросов API (или пайплайн запросов, или последовательные вызовы API) — это техника, используемая в разработке программного обеспечения для управления сложностью взаимодействий API, когда программное обеспечение требует нескольких вызовов API для выполнения задачи. Это похоже на обработку пакетных запросов, где вы группируете несколько запросов API в один запрос и отправляете их на сервер как пакет. Хотя они могут казаться похожими, пайплайн запрос предполагает отправку одного запроса на сервер, который запускает последовательность запросов API, выполняемых в определенном порядке. Каждый запрос API в последовательности может изменять данные запроса и ответа, а ответ от одного запроса API передается как входные данные для следующего запроса API в последовательности. Пайплайн запросы могут быть полезны, когда клиенту необходимо выполнить последовательность зависимых запросов API, которые должны быть выполнены в определенном порядке.
На каждом шаге пайплайна мы можем преобразовывать или манипулировать данными ответа перед передачей их на следующий шаг. Это может быть полезно в ситуациях, когда данные необходимо нормализовать или преобразовать или отфильтровать конфиденциальные данные перед возвращением их клиенту. Это может помочь снизить общую задержку. Например, один вызов API может быть выполнен, пока другой ожидает ответа, что сокращает общее время, необходимое для завершения рабочего процесса.

Пользовательский плагин pipeline-request для Apache APISIX
API Gateway может быть подходящим местом для реализации этой функциональности, так как он может перехватывать все запросы клиентских приложений и перенаправлять их на целевые адреса. Мы будем использовать Apache APISIX, так как это популярное решение с открытым исходным кодом для API Gateway с множеством встроенных плагинов. Однако на момент разработки текущего блога APISIX не имел официальной поддержки плагина pipeline-request. Зная о возможностях разработки пользовательских плагинов в APISIX, мы решили представить новый плагин, который может предложить ту же функциональность. На GitHub есть репозиторий с исходным кодом, написанным на языке Lua, и описанием плагина pipeline-request.
С этим плагином вы можете указать список вышестоящих API, которые должны вызываться последовательно для обработки одного клиентского запроса. Каждый вышестоящий API может изменять данные запроса и ответа, а ответ от одного вышестоящего API передается как входные данные для следующего вышестоящего API в пайплайне. Пайплайн может быть определен в конфигурации Route, и вы также можете определить порядок выполнения API URL в пайплайне.
Давайте рассмотрим использование этого плагина на примере. Предположим, у вас есть два API — один делает GET-запрос /credit_cards для получения информации о кредитных картах, а другой получает данные предыдущего ответа в теле POST-запроса /filter, а затем фильтрует конфиденциальные данные (например, номер кредитной карты и срок действия) перед возвращением ответа клиенту. Поскольку конечная точка API кредитных карт возвращает конфиденциальную информацию, которая не должна быть доступна неавторизованным сторонам. На следующей диаграмме показан общий поток данных:

- Когда клиент делает запрос к конечной точке API кредитных карт API Gateway для получения всей информации о кредитных картах, API Gateway перенаправляет запрос на получение данных о кредитных картах из сервиса кредитных карт.
- Если запрос успешен и возвращает данные о кредитных картах, они передаются на следующий шаг пайплайна, который является сервисом безопасности.
- Когда отфильтрованный ответ получен от сервиса безопасности, он возвращает объединенный ответ клиенту.
Демонстрация плагина pipeline-request
Для этой демонстрации мы будем использовать подготовленный демонстрационный проект на GitHub, где вы можете найти все примеры команд curl, используемые в этом руководстве, запустить APISIX и включить пользовательский плагин без дополнительной конфигурации с помощью файла Docker compose.yml.
Предварительные требования
- Docker используется для установки контейнеризованных etcd и APISIX.
- curl используется для отправки запросов к API администратора APISIX. Вы также можете использовать удобные инструменты, такие как Postman, для взаимодействия с API.
Шаг 1: Установка и запуск APISIX и etcd
Вы можете легко установить APISIX и etcd, выполнив команду docker compose up из корневой папки проекта после того, как вы форкнете/клонируете проект. Вы можете заметить, что в файле docker-compose.yml указан том ./custom-plugins:/opt/apisix/plugins:ro. Это монтирует локальную директорию ./custom-plugins, где находится наш файл pipeline-request.lua с реализацией пользовательского плагина, как том только для чтения в контейнере Docker по пути /opt/apisix/plugins. Это позволяет добавлять пользовательские плагины в APISIX во время выполнения (эта настройка применима только если вы запускаете APISIX с Docker).
Шаг 2: Создание первого Route с плагином pipeline-request
После запуска APISIX мы используем команду cURL, которая отправляет HTTP PUT-запрос к конечной точке API администратора APISIX /routes для создания нашего первого маршрута, который прослушивает путь URI /my-credit-cards.
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ --header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \ --header 'Content-Type: application/json' \ --data-raw '{ "uri":"/my-credit-cards", "plugins":{ "pipeline-request":{ "nodes":[ { "url":"https://random-data-api.com/api/v2/credit_cards" }, { "url":"http://127.0.0.1:9080/filter" } ] } } }'
Важной частью конфигурации является раздел "plugins", который указывает, что для этого маршрута API должен использоваться плагин "pipeline-request". Конфигурация плагина содержит массив "nodes", который определяет последовательность запросов API, которые должны быть выполнены в пайплайне. Вы можете определить один или несколько API. В данном случае пайплайн состоит из двух узлов: первый узел отправляет запрос к API https://random-data-api.com/api/v2/credit_cards для получения данных о кредитных картах, а второй узел отправляет запрос к локальному API по адресу http://127.0.0.1:9080/filter для фильтрации конфиденциальных данных из информации о кредитных картах. Второй API будет просто серверной функцией, использующей плагин serverless-pre-function APISIX. Он действует как серверная служба для изменения ответа от первого API.
Шаг 3: Создание второго Route с плагином serverless
Далее мы настраиваем новый маршрут с ID 2, который обрабатывает запросы к конечной точке /filter в пайплайне. Он также включает serverless-pre-function существующий плагин APISIX, где мы указываем функцию Lua, которая должна быть выполнена плагином. Эта функция просто извлекает тело запроса из предыдущего ответа, заменяет поле номера кредитной карты и оставляет остальную часть ответа неизменной. Наконец, она устанавливает текущее тело ответа на измененное тело запроса и отправляет HTTP 200 ответ обратно клиенту. Вы можете изменить этот скрипт в соответствии с вашими потребностями, например, используя декодированное тело для выполнения дальнейшей обработки или проверки.
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/2' \ --header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \ --header 'Content-Type: application/json' \ --data-raw ' { "uri": "/filter", "plugins":{ "serverless-pre-function": { "phase": "access", "functions": [ "return function(conf, ctx) local core = require(\"apisix.core\") local cjson = require(\"cjson.safe\") -- Get the request body local body = core.request.get_body() -- Decode the JSON body local decoded_body = cjson.decode(body) -- Hide the credit card number decoded_body.credit_card_number = \"****-****-****-****\" core.response.exit(200, decoded_body); end" ] } } }'
Шаг 3: Тестирование настройки
Теперь пришло время протестировать общую конфигурацию. С помощью следующей команды curl мы отправляем HTTP GET-запрос к конечной точке http://127.0.0.1:9080/my-credit-cards.
curl http://127.0.0.1:9080/my-credit-cards
У нас есть соответствующий маршрут, настроенный на втором шаге для использования плагина pipeline-request с двумя узлами, этот запрос запустит пайплайн для получения информации о кредитных картах с конечной точки https://random-data-api.com/api/v2/credit_cards, фильтрации конфиденциальных данных с использованием конечной точки http://127.0.0.1:9080/filter и возвращения измененного ответа клиенту. Смотрите вывод:
{ "uid":"a66239cd-960b-4e14-8d3c-a8940cedd907", "credit_card_expiry_date":"2025-05-10", "credit_card_type":"visa", "credit_card_number":"****-****-****-****", "id":2248 }
Как видите, он заменяет номер кредитной карты в теле запроса (на самом деле, это ответ от первого вызова API в цепочке) на звездочки.
Итог
До сих пор мы узнали, что наш пользовательский плагин pipeline-request для API Gateway Apache APISIX позволяет нам определять последовательность вызовов API как пайплайн в определенном порядке. Мы также можем использовать этот новый плагин в сочетании с существующими для включения аутентификации, безопасности и других функций API Gateway для наших конечных точек API.