Plugin Serverless de Apache APISIX para Event Hooks
February 15, 2023
Apache APISIX es una puerta de enlace de API de alto rendimiento y de código abierto construida sobre Nginx. Una de sus características más potentes es la capacidad de crear funciones sin servidor (serverless), que son programas pequeños y sin estado que pueden extender la funcionalidad de Apache APISIX. En este artículo, cubriremos los conceptos básicos del plugin serverless de Apache APISIX y cómo se puede utilizar para activar funciones sin servidor en respuesta a eventos.
Objetivos de aprendizaje
A lo largo del artículo, aprenderás lo siguiente:
- ¿Qué es el plugin serverless de Apache APISIX?
- ¿Cómo funciona el plugin serverless y cómo usarlo?
- Casos de uso del plugin serverless.
- Cómo puedes usar el plugin serverless para integrarlo con un webhook.
¿Qué es el plugin serverless de Apache APISIX?
El plugin serverless de Apache APISIX para enlaces de eventos te permite escribir funciones sin servidor e integrarlas en la puerta de enlace de API. El plugin proporciona una forma simple y flexible de ejecutar código personalizado en respuesta a eventos, sin necesidad de gestionar la infraestructura subyacente.
El plugin serverless separa la lógica para manejar eventos en funciones sin servidor independientes, lo que te permite simplificar la arquitectura de tu API y facilitar su gestión. Apache APISIX ofrece soporte para frameworks serverless de proveedores de nube populares como Azure Functions y AWS Lambda.
¿Cómo usar el plugin serverless?
Para usar el plugin serverless de Apache APISIX para enlaces de eventos, necesitarás escribir un código de función sin servidor en el lenguaje de programación Lua que implemente la lógica que deseas ejecutar en respuesta a un evento y habilitar el plugin serverless-pre-function
o serverless-post-function
según las fases del ciclo de solicitud-respuesta que elijas.
Actualmente, APISIX solo admite Lua para escribir código de funciones. Si prefieres otros lenguajes de programación, siempre puedes usar plugin runners para crear un nuevo plugin personalizado desde cero.
Casos de uso del plugin serverless
Aquí hay algunos casos de uso para el plugin serverless de Apache APISIX para enlaces de eventos:
-
Enrutamiento dinámico: El plugin serverless puede usarse para enrutar dinámicamente solicitudes de API entrantes según criterios específicos, como el método de solicitud, la ruta de la URL o los valores de los encabezados. Esto te permite implementar fácilmente escenarios de enrutamiento complejos sin necesidad de modificar la configuración subyacente de Apache APISIX.
-
Autenticación y autorización: Puedes usar el plugin serverless para implementar verificaciones de autenticación y autorización para tu API. Por ejemplo, puedes escribir una función sin servidor que verifique la presencia de una clave de API válida en los encabezados de la solicitud antes de permitir que la solicitud continúe. O puede usarse como un servicio de autorización externa en combinación con el plugin forward-auth.
-
Transformación de solicitudes: El plugin serverless puede usarse para transformar solicitudes de API entrantes antes de que sean procesadas por el servicio backend. Por ejemplo, puedes escribir una función sin servidor que modifique los encabezados o el cuerpo de la solicitud para que coincidan con el formato esperado por el servicio backend.
-
Transformación de respuestas: También puedes usar el plugin serverless para transformar la respuesta del servicio backend antes de que se envíe de vuelta al cliente. Por ejemplo, puedes escribir una función sin servidor que modifique los encabezados o el cuerpo de la respuesta para que coincidan con el formato esperado por el cliente.
-
Registro y monitoreo: Puedes usar el plugin serverless para implementar registro y monitoreo para tu API. Por ejemplo, puedes escribir una función sin servidor que registre información detallada sobre cada solicitud de API, como el método de solicitud, la URL, los encabezados y el cuerpo, para su posterior análisis.
Integración de Apache APISIX con webhooks (Demo)
Para integrar Apache APISIX con webhooks, necesitas crear una función sin servidor que escuche las solicitudes POST entrantes al punto final de la URL, verifique si el método de solicitud es POST y envíe una notificación de webhook al servicio de terceros cada vez que se publique un nuevo mensaje.
La función sin servidor también debe devolver la respuesta del webhook, para que puedas ver el estado del webhook y cualquier mensaje de error si algo sale mal. En ambos casos, APISIX puede comunicarse con el servicio de destino, informándole que se activó un evento llamando a una URL proporcionada con información sobre ese evento.
Requisitos previos
- Docker instalado en tu máquina para ejecutar APISIX.
- Conocimientos básicos sobre algunos conceptos principales de APISIX, como Route, Upstream y Plugin.
Configuración del proyecto
Lo primero que debes hacer es clonar el repositorio del proyecto apisix-docker desde GitHub:
git clone https://github.com/apache/apisix-docker.git
Abre la carpeta del proyecto en tu editor de código favorito. Este tutorial utiliza VS Code.
Instalar y ejecutar Apache APISIX
Para ejecutar Apache APISIX, puedes seguir estos pasos:
Abre una nueva ventana de terminal y ejecuta el comando docker compose up
desde la carpeta raíz del proyecto:
docker compose up -d
El comando anterior ejecutará Apache APISIX y etcd juntos con Docker.
En esta demo, instalamos APISIX usando Docker. Sin embargo, hay otras opciones para instalarlo en la guía de instalación.
Configurar la función sin servidor en Apache APISIX
Para configurar la función sin servidor en Apache APISIX, necesitas crear una nueva ruta para el punto final y configurar el plugin serverless con nuestro código de función personalizado en Lua.
Aquí hay un ejemplo de una función sin servidor en Lua que escucha las solicitudes POST entrantes al punto final y envía una notificación de webhook:
function webhook(conf, ctx)
-- Importar las bibliotecas necesarias
local http = require("resty.http")
local core = require("apisix.core")
-- Enviar la notificación de webhook solo si el método de solicitud es POST, de lo contrario, omitir y enviarlo al upstream como de costumbre
if core.request.get_method() == "POST" then
-- Enviar la notificación de webhook a la URL especificada
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(),
})
-- Verificar la respuesta del webhook
if not res then
core.log.error("Error al enviar el webhook: ", err)
return 500, err
end
end
-- Devolver la respuesta del servicio upstream
return conf.status, conf.body
end
Como puedes ver en el código de ejemplo de la función webhook anterior, realiza solicitudes POST JSON a una URL proporcionada con el cuerpo de la solicitud (el cuerpo de la solicitud del cliente a la puerta de enlace de API) como carga útil. Se utiliza el sitio web de pruebas de webhooks para simular nuestro punto final de webhook: https://webhook.site.
Para crear y configurar tu punto final de webhook:
- Genera una URL navegando a https://webhook.site en tu navegador web.
- Selecciona Copiar al portapapeles junto a Your unique URL.
- Pégala en el método request_uri de la solicitud HTTP en el código de la función.
Además, todas las demás solicitudes, incluidas las POST, se reenviarán al servicio upstream. En el siguiente paso, configuramos una ruta y un upstream.
Configurar una Ruta y un Upstream
Ahora crearemos una nueva ruta con el plugin de función sin servidor habilitado y un upstream que actúa como nuestro servicio backend.
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)
-- Importar las bibliotecas necesarias
local http = require(\"resty.http\")
local core = require(\"apisix.core\")
-- Enviar la notificación de webhook solo si el método de solicitud es POST, de lo contrario, omitir y enviarlo al upstream como de costumbre
if core.request.get_method() == \"POST\" then
-- Enviar la notificación de webhook a la URL especificada
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(),
})
-- Verificar la respuesta del webhook
if not res then
core.log.error(\"Error al enviar el webhook: \", err)
return 500, err
end
end
-- Devolver la respuesta del servicio upstream
return conf.status, conf.body
end"]
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}
}'
En el ejemplo anterior de configuración de ruta, creamos nuestra primera ruta enviando una solicitud curl
a la API de administración de APISIX. En el cuerpo de la solicitud de la ruta, especificamos que cualquier solicitud a la ruta /post
activará el código de la función sin servidor y se reenviará posteriormente al destino httpbin.org
. Esto significa que la solicitud se enrutará al punto final httpbin.org/post
después de verificar si el método de solicitud es POST y si el evento debe enviarse al punto final de webhook del servicio de terceros o no. El servicio backend puede ser reemplazado por tu propio servicio backend.
También puedes notar que agregamos el código de la función en las propiedades functions
de serverless-pre-function
en el objeto Json.
Probar la configuración
Finalmente, probamos llamando al punto final /post
de la puerta de enlace de API para verificar si todo funciona como esperamos y el evento POST se enviará al sitio web de webhook.
curl -i http://127.0.0.1:9080/post -X POST -d \
'{
"message": "A new webhook message"
}'
Después, navega a la URL del webhook desde la página https://webhook.site que generaste en los pasos anteriores. Deberías ver una solicitud POST, notificando a nuestro punto final de webhook sobre el evento y enviando el cuerpo de la solicitud.
Además de esto, obtenemos la respuesta del servicio mock upstream 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"
}
Obviamente, si envías otros métodos de solicitudes HTTP aparte de POST, el código de la función sin servidor no activará el punto final de webhook.
Este es un ejemplo básico de cómo configurar una función sin servidor en Apache APISIX. Puedes extender esta funcionalidad agregando una lógica más compleja a tu función sin servidor, como activar otra función en respuesta a webhooks.
Conclusión
El plugin serverless de Apache APISIX para enlaces de eventos proporciona una forma flexible y escalable de activar funciones sin servidor en respuesta a eventos que ocurren durante el procesamiento de solicitudes de API. Al usar el plugin, puedes simplificar la arquitectura de tu API, mejorar el rendimiento y la confiabilidad de tus servicios, y reducir el costo de gestionar la infraestructura de tu aplicación.
Recursos relacionados
Contenido recomendado
Comunidad
🙋 Únete a la comunidad de Apache APISIX 🐦 Síguenos en Twitter 📝 Encuéntranos en Slack