Apache APISIX Serverless Plugin для Event Hooks

Bobur Umurzokov

Bobur Umurzokov

February 15, 2023

Technology

Apache APISIX — это высокопроизводительный API-шлюз с открытым исходным кодом, построенный на основе Nginx. Одной из его мощных функций является возможность создания бессерверных функций (serverless functions) — небольших программ без состояния, которые могут расширять функциональность Apache APISIX. В этой статье мы рассмотрим основы плагина serverless в Apache APISIX и то, как его можно использовать для запуска бессерверных функций в ответ на события.

Цели обучения

В этой статье вы узнаете следующее:

  • Что такое плагин serverless в Apache APISIX?
  • Как работает плагин serverless и как его использовать?
  • Примеры использования плагина serverless.
  • Как можно использовать плагин serverless для интеграции с вебхуком.

Что такое плагин serverless в Apache APISIX?

Плагин serverless в Apache APISIX для обработки событий позволяет писать бессерверные функции и интегрировать их в API-шлюз. Этот плагин предоставляет простой и гибкий способ запуска пользовательского кода в ответ на события, без необходимости управления базовой инфраструктурой.

Плагин serverless разделяет логику обработки событий на отдельные бессерверные функции, что упрощает архитектуру API и облегчает управление. Apache APISIX поддерживает бессерверные фреймворки для популярных облачных провайдеров, таких как Azure Functions и AWS Lambda.

Как использовать плагин serverless?

Чтобы использовать плагин serverless в Apache APISIX для обработки событий, необходимо написать код бессерверной функции на языке программирования Lua, который реализует логику, которую вы хотите выполнить в ответ на событие, и включить плагин serverless-pre-function или serverless-post-function в зависимости от выбранной фазы цикла запрос-ответ.

В настоящее время APISIX поддерживает только Lua для написания кода функций. Если вы предпочитаете другие языки программирования, вы всегда можете использовать plugin runners для создания нового пользовательского плагина с нуля.

Примеры использования плагина serverless

Вот несколько примеров использования плагина serverless в Apache APISIX для обработки событий:

  1. Динамическая маршрутизация: Плагин serverless можно использовать для динамической маршрутизации входящих API-запросов на основе определенных критериев, таких как метод запроса, путь URL или значения заголовков. Это позволяет легко реализовать сложные сценарии маршрутизации без необходимости изменения базовой конфигурации Apache APISIX.

  2. Аутентификация и авторизация: Вы можете использовать плагин serverless для реализации проверок аутентификации и авторизации для вашего API. Например, можно написать бессерверную функцию, которая проверяет наличие действительного API-ключа в заголовках запроса перед тем, как разрешить запрос продолжить выполнение. Или её можно использовать как внешний сервис авторизации в сочетании с плагином forward-auth.

  3. Трансформация запросов: Плагин serverless можно использовать для трансформации входящих API-запросов перед их обработкой серверной службой. Например, можно написать бессерверную функцию, которая изменяет заголовки или тело запроса в соответствии с форматом, ожидаемым серверной службой.

  4. Трансформация ответов: Вы также можете использовать плагин serverless для трансформации ответа от серверной службы перед его отправкой клиенту. Например, можно написать бессерверную функцию, которая изменяет заголовки или тело ответа в соответствии с форматом, ожидаемым клиентом.

  5. Логирование и мониторинг: Плагин serverless можно использовать для реализации логирования и мониторинга вашего API. Например, можно написать бессерверную функцию, которая логирует подробную информацию о каждом API-запросе, такую как метод запроса, URL, заголовки и тело, для последующего анализа.

Интеграция Apache APISIX с вебхуками (Демо)

Для интеграции Apache APISIX с вебхуками необходимо создать бессерверную функцию, которая прослушивает входящие POST-запросы к конечной точке URL, проверяет, является ли метод запроса POST, и отправляет уведомление вебхука стороннему сервису, когда публикуется новое сообщение.

Бессерверная функция также должна возвращать ответ от вебхука, чтобы можно было увидеть статус вебхука и любые сообщения об ошибках, если что-то пойдет не так. В обоих случаях APISIX может взаимодействовать с целевым сервисом, уведомляя его о том, что событие было вызвано, путем вызова предоставленного URL с информацией об этом событии.

APISIX отправляет POST-запрос вебхуку

Предварительные требования

  • Установленный Docker на вашем компьютере для запуска APISIX.
  • Базовые знания о ключевых концепциях APISIX, таких как Route, Upstream и Plugin.

Настройка проекта

Первым делом клонируйте репозиторий проекта apisix-docker с GitHub:

git clone https://github.com/apache/apisix-docker.git

Откройте папку проекта в вашем любимом редакторе кода. В этом руководстве используется VS Code.

Установка и запуск Apache APISIX

Для запуска Apache APISIX выполните следующие шаги:

Откройте новое окно терминала и выполните команду docker compose up из корневой папки проекта:

docker compose up -d

Эта команда запустит Apache APISIX и etcd вместе с Docker.

В этом демо мы установили APISIX с помощью Docker. Однако есть и другие способы установки, описанные в руководстве по установке.

Настройка бессерверной функции в Apache APISIX

Чтобы настроить бессерверную функцию в Apache APISIX, необходимо создать новый маршрут для конечной точки и настроить плагин serverless с нашим пользовательским кодом функции на Lua.

Вот пример бессерверной функции на Lua, которая прослушивает входящие POST-запросы к конечной точке и отправляет уведомление вебхука:

function webhook(conf, ctx) -- Импорт необходимых библиотек local http = require("resty.http") local core = require("apisix.core") -- Отправка уведомления вебхука только если метод запроса POST, иначе пропустить и отправить запрос в upstream как обычно if core.request.get_method() == "POST" then -- Отправка уведомления вебхука на указанный URL local httpc = http.new() local res, err = httpc:request_uri("http://webhook.site/9db3d3a0-ab64-4142-a39f-d4852ca50f8d", { method = "POST", headers = { ["Content-Type"] = "application/json" }, body = core.request.get_body(), }) -- Проверка ответа от вебхука if not res then core.log.error("Не удалось отправить вебхук: ", err) return 500, err end end -- Возврат ответа от серверной службы return conf.status, conf.body end

Как видно из приведенного выше примера кода функции вебхука, он отправляет JSON POST-запросы на указанный URL с телом запроса (тело запроса от клиента к API-шлюзу) в качестве полезной нагрузки. Для тестирования вебхуков используется сайт https://webhook.site, который имитирует нашу конечную точку вебхука.

Чтобы создать и настроить вашу конечную точку вебхука:

  1. Сгенерируйте URL, перейдя на https://webhook.site в вашем браузере.
  2. Выберите Скопировать в буфер обмена рядом с Ваш уникальный URL.
  3. Вставьте его в метод request_uri HTTP-запроса в коде функции.

Также все остальные запросы, включая POST, будут перенаправлены дальше в серверную службу. На следующем шаге мы настроим маршрут и upstream.

Настройка маршрута и upstream

Теперь мы создадим новый маршрут с включенным плагином serverless и upstream, который будет выступать в качестве нашей серверной службы.

curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \ -H 'Content-Type: application/json' \ -d '{ "uri": "/post", "plugins": { "serverless-pre-function": { "phase": "rewrite", "functions" : [" return function(conf, ctx) -- Импорт необходимых библиотек local http = require(\"resty.http\") local core = require(\"apisix.core\") -- Отправка уведомления вебхука только если метод запроса POST, иначе пропустить и отправить запрос в upstream как обычно if core.request.get_method() == \"POST\" then -- Отправка уведомления вебхука на указанный URL local httpc = http.new() local res, err = httpc:request_uri(\"http://webhook.site/9db3d3a0-ab64-4142-a39f-d4852ca50f8d\", { method = \"POST\", headers = { [\"Content-Type\"] = \"application/json\" }, body = core.request.get_body(), }) -- Проверка ответа от вебхука if not res then core.log.error(\"Не удалось отправить вебхук: \", err) return 500, err end end -- Возврат ответа от серверной службы return conf.status, conf.body end"] } }, "upstream": { "nodes": { "httpbin.org:80": 1 }, "type": "roundrobin" } }'

В приведенном примере конфигурации маршрута мы создали наш первый маршрут, отправив curl-запрос к Admin API APISIX. В теле запроса маршрута мы указали, что любые запросы к пути /post будут запускать код бессерверной функции и затем перенаправляться на целевой httpbin.org. Это означает, что запрос будет перенаправлен на конечную точку httpbin.org/post после проверки, является ли метод запроса POST и должно ли событие быть отправлено на конечную точку вебхука стороннего сервиса или нет. Серверная служба может быть заменена на вашу собственную.

Вы также можете заметить, что мы добавили код функции в свойства functions плагина serverless-pre-function в JSON-объекте.

Тестирование конфигурации

Наконец, мы тестируем, вызывая конечную точку /post API-шлюза, чтобы убедиться, что всё работает, как ожидалось, и событие POST будет отправлено на сайт вебхука.

curl -i http://127.0.0.1:9080/post -X POST -d \ '{ "message": "A new webhook message" }'

После этого перейдите на URL вебхука с сайта https://webhook.site, который вы сгенерировали на предыдущих шагах. Вы должны увидеть POST-запрос, уведомляющий нашу конечную точку вебхука о событии и отправляющий тело запроса.

APISIX отправляет полезную нагрузку вебхуку

Кроме того, мы получаем ответ от макетной серверной службы httpbin.org:

HTTP/1.1 200 OK Content-Type: application/json { ... "form": { "{\n \"message\": \"A new webhook message\"\n}": "" }, "headers": { "Accept": "*/*", "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded", "Host": "127.0.0.1", "X-Forwarded-Host": "127.0.0.1" }, "json": null, "url": "http://127.0.0.1/post" }

Очевидно, что если вы отправляете другие методы HTTP-запросов, кроме POST, код бессерверной функции не будет запускать конечную точку вебхука.

Это базовый пример настройки бессерверной функции в Apache APISIX. Вы можете расширить эту функциональность, добавив более сложную логику в вашу бессерверную функцию, например, запуск другой функции в ответ на вебхуки.

Заключение

Плагин serverless в Apache APISIX для обработки событий предоставляет гибкий и масштабируемый способ запуска бессерверных функций в ответ на события, происходящие во время обработки API-запросов. Используя этот плагин, вы можете упростить архитектуру вашего API, повысить производительность и надежность ваших сервисов, а также снизить затраты на управление инфраструктурой приложения.

Связанные ресурсы

Рекомендуемые материалы

Сообщество

🙋 Присоединяйтесь к сообществу Apache APISIX 🐦 Следите за нами в Twitter 📝 Найдите нас в Slack

Tags: