Procesamiento de Solicitudes por Lotes con API Gateway
April 27, 2023
El procesamiento de solicitudes por lotes es una técnica poderosa utilizada en el desarrollo web para mejorar el rendimiento de las API. Permite a los desarrolladores agrupar múltiples solicitudes de API en un solo ciclo de solicitud/respuesta HTTP. En otras palabras, una sola solicitud de API desde un cliente puede convertirse en múltiples solicitudes de API a un conjunto de servidores backend, y las respuestas se agregan en una sola respuesta para el cliente. Esto puede reducir significativamente el número de viajes de ida y vuelta entre el cliente y el servidor.
En este artículo, exploraremos cómo implementar el procesamiento de solicitudes por lotes en Apache APISIX y veremos algunos casos de uso en los que puede ser beneficioso.
Es similar al patrón de Composición de API, que se aplica ampliamente en la arquitectura de microservicios.
¿Por qué usar el procesamiento de solicitudes por lotes?
Cuando un cliente envía múltiples solicitudes de API a un servidor, cada solicitud requiere un ciclo de solicitud/respuesta HTTP separado. Esto puede resultar en una mayor latencia, un rendimiento reducido y una mayor carga en el servidor. Al agrupar múltiples solicitudes en una sola solicitud por lotes, se puede reducir el número de ciclos de solicitud/respuesta HTTP, lo que resulta en un mejor rendimiento y una menor latencia.
El procesamiento de solicitudes por lotes puede ser particularmente útil en escenarios donde necesitas recuperar o actualizar múltiples registros en una sola transacción, como:
- Recuperar múltiples registros de una base de datos
- Actualizar múltiples registros en una base de datos
- Ejecutar múltiples solicitudes de API para completar una tarea
Ejemplos del mundo real para el procesamiento de solicitudes por lotes
Ejemplo 1:
Supongamos que tienes una aplicación de redes sociales que muestra el feed de un usuario, que incluye publicaciones de sus amigos y las páginas que sigue. Para llenar este feed, necesitas hacer múltiples solicitudes de API para recuperar los datos necesarios, como:
- Recuperar una lista de los amigos del usuario y las páginas que sigue.
- Para cada amigo o página, recuperar sus publicaciones recientes.
En un enfoque tradicional, realizarías cada una de estas solicitudes de API por separado. Primero, recuperarías una lista de amigos del usuario y, en la segunda solicitud, obtendrías las publicaciones recientes de cada amigo del usuario. Esto puede resultar en una mayor latencia, especialmente cuando el usuario tiene un gran número de amigos y sigue muchas páginas.
Ejemplo 2:
Otro ejemplo, tienes una aplicación móvil que muestra una lista de productos para que los usuarios los exploren. Para llenar esta lista, necesitas hacer múltiples solicitudes de API para recuperar datos de productos de un servidor remoto, como:
- Recuperar una lista de IDs de productos.
- Para cada ID de producto, recuperar los detalles del producto (nombre, descripción, imagen, etc.)
Ejemplo 3:
Imagina que tienes una aplicación web para la gestión de conferencias donde hay múltiples ponentes en el sistema y deseas mostrar las sesiones y temas relacionados de un ponente en una sola página web. Un servicio backend Conference API tiene dos endpoints diferentes /speaker/{speakerId}/sessions
y /speaker/{speakerId}/topics
para exponer esta información. Para mostrar tanto las sesiones como los temas que pertenecen a un solo ponente, puedes enviar dos solicitudes desde la aplicación frontend, lo cual no es una solución ideal. En su lugar, puedes usar una API Gateway para agrupar todas estas solicitudes en una sola solicitud HTTP, como se explica en la siguiente sección.
Procesamiento de solicitudes por lotes con Apache APISIX API Gateway
Para implementar el procesamiento de solicitudes por lotes en APISIX, puedes usar el plugin batch-requests. Este plugin te permite definir un conjunto de solicitudes de API en un solo payload de solicitud HTTP POST
. Cada solicitud puede tener su propio método HTTP, ruta URL, conjunto de encabezados y payload. A continuación, se muestra un comando de solicitud curl para el ejemplo 3 (solicitudes de Conference API):
curl -i http://{API_GATEWAY_HOST_ADDRESS}/speaker -X POST -d \
'{
"pipeline": [
{
"method": "GET",
"path": "/speaker/1/topics"
},
{
"method": "GET",
"path": "/speaker/1/sessions"
}
]
}'
Cuando APISIX recibe una solicitud por lotes, el plugin batch-requests analizará el payload y ejecutará cada solicitud en el lote en paralelo. El plugin también agregará las respuestas de cada solicitud y las devolverá en una sola respuesta HTTP al cliente. Consulta la siguiente sección de demostración para aprender cómo lograr esto paso a paso.
Demostración del plugin de solicitudes por lotes
Antes de poder usar el plugin batch-requests, necesitarás instalar Apache APISIX.
Requisitos previos
- Docker se utiliza para instalar etcd y APISIX en contenedores.
- curl se utiliza para enviar solicitudes a la API de administración de APISIX. También puedes usar herramientas fáciles como Postman para interactuar con la API.
APISIX se puede instalar y ejecutar fácilmente con el siguiente script de inicio rápido:
curl -sL <https://run.api7.ai/apisix/quickstart> | sh
Configurar el servicio backend (upstream)
Necesitarás configurar el servicio backend para Conference API al que deseas enrutar las solicitudes. Esto se puede hacer agregando un servidor upstream en Apache APISIX a través de la API de administración.
curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -X PUT -d '
{
"name": "Conferences API upstream",
"desc": "Registrar Conference API como el upstream",
"type": "roundrobin",
"scheme": "https",
"nodes": {
"conferenceapi.azurewebsites.net:443": 1
}
}'
Crear una ruta para la API de procesamiento por lotes
Necesitamos crear una nueva ruta que intercepte las solicitudes a /speaker
y exponga un endpoint virtual público para el procesamiento por lotes utilizando el plugin [public-api](https://apisix.apache.org/docs/apisix/plugins/public-api/)
.
curl http://127.0.0.1:9180/apisix/admin/routes/a -X PUT -d '
{
"uri": "/speaker",
"plugins": {
"public-api": {
"uri": "/apisix/batch-requests"
}
}
}'
Crear una ruta para los endpoints de temas y sesiones del ponente
A continuación, creamos otra ruta para los endpoints de temas y sesiones del ponente (/speaker/*/topics
y /speaker/*/sessions
que coincidan con las rutas) para que las solicitudes individuales extraídas por la API Gateway de las solicitudes por lotes para recuperar los temas o sesiones del ponente se reenvíen a los endpoints responsables de Conference API y referenciamos el servicio upstream existente.
curl http://127.0.0.1:9180/apisix/admin/routes/b -X PUT -d '
{
"methods": ["GET"],
"uris": ["/speaker/*/topics","/speaker/*/sessions"],
"plugins": {
"proxy-rewrite":{
"host":"conferenceapi.azurewebsites.net"
}
},
"upstream_id":"1"
}'
Puedes notar que estamos usando otro plugin proxy-rewrite y especificando implícitamente la dirección del host para Conference API. De lo contrario, la API Gateway puede hacer la conversión DNS y solicitar la Conference API por su dirección IP.
Probar el procesamiento de solicitudes por lotes
Aquí hay un ejemplo de cómo usar el plugin batch-requests en APISIX:
curl -i http://127.0.0.1:9080/speaker -X POST -d \
'{
"pipeline": [
{
"method": "GET",
"path": "/speaker/1/topics"
},
{
"method": "GET",
"path": "/speaker/1/sessions"
}
]
}'
En este ejemplo, la ruta está definida para el endpoint /speaker
, que admite el procesamiento de solicitudes por lotes a través del plugin batch-requests. El plugin está configurado con un conjunto de dos solicitudes, cada una recuperando un registro de ponente por ID con temas y sesiones. Si ejecutas este comando, obtendrás una respuesta combinada de la API Gateway:
[
{
"body":"{\r\n \"collection\": {\r\n \"version\": \"1.0\",\r\n \"links\": [],\r\n \"items\": [\r\n {\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/8\",\r\n \"data\": [\r\n {\r\n \"name\": \"Title\",\r\n \"value\": \"Microsoft\"\r\n }\r\n ],\r\n \"links\": [\r\n {\r\n \"rel\": \"http://tavis.net/rels/sessions\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/8/sessions\"\r\n }\r\n ]\r\n },\r\n {\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/10\",\r\n \"data\": [\r\n {\r\n \"name\": \"Title\",\r\n \"value\": \"Mobile\"\r\n }\r\n ],\r\n \"links\": [\r\n {\r\n \"rel\": \"http://tavis.net/rels/sessions\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/10/sessions\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"queries\": [],\r\n \"template\": {\r\n \"data\": []\r\n }\r\n }\r\n}",
"status":200,
"headers":{
"Expires":"-1",
"Connection":"keep-alive",
"Pragma":"no-cache",
"Content-Length":"953",
"Server":"APISIX/3.2.0",
"Content-Type":"application/vnd.collection+json",
"X-AspNet-Version":"4.0.30319",
"Cache-Control":"no-cache",
"X-Powered-By":"ASP.NET"
},
"reason":"OK"
},
{
"body":"{\r\n \"collection\": {\r\n \"version\": \"1.0\",\r\n \"links\": [],\r\n \"items\": [\r\n {\r\n \"href\": \"https://conferenceapi.azurewebsites.net/session/206\",\r\n \"data\": [\r\n {\r\n \"name\": \"Title\",\r\n \"value\": \"\\r\\n\\t\\t\\tjQuery Mobile and ASP.NET MVC\\r\\n\\t\\t\"\r\n },\r\n {\r\n \"name\": \"Timeslot\",\r\n \"value\": \"05 December 2013 09:00 - 10:00\"\r\n },\r\n {\r\n \"name\": \"Speaker\",\r\n \"value\": \"Scott Allen\"\r\n }\r\n ],\r\n \"links\": [\r\n {\r\n \"rel\": \"http://tavis.net/rels/speaker\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/speaker/16\"\r\n },\r\n {\r\n \"rel\": \"http://tavis.net/rels/topics\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/session/206/topics\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"queries\": [],\r\n \"template\": {\r\n \"data\": []\r\n }\r\n }\r\n}",
"status":200,
"headers":{
"Expires":"-1",
"Connection":"keep-alive",
"Pragma":"no-cache",
"Content-Length":"961",
"Server":"APISIX/3.2.0",
"Content-Type":"application/vnd.collection+json",
"X-AspNet-Version":"4.0.30319",
"Cache-Control":"no-cache",
"X-Powered-By":"ASP.NET"
},
"reason":"OK"
}
]
El tamaño máximo de una solicitud por lotes está limitado por la API Gateway. Puedes consultar la documentación de la API Gateway para conocer los límites actuales y la configuración del tiempo de espera de la solicitud.
Conclusiones
- El procesamiento de solicitudes por lotes con API Gateway puede ser una técnica útil para mejorar el rendimiento de tu API.
- Apache APISIX proporciona un plugin llamado
batch-requests
que permite a los desarrolladores implementar fácilmente el procesamiento de solicitudes por lotes.
Próximos pasos
Con API Gateway, también es posible proporcionar alguna forma de agregación personalizada en los datos de respuesta para tus usuarios. Puedes usar el plugin serverless-function para ejecutar código personalizado y fusionar la respuesta de los servicios backend y devolverla al consumidor de la API en una estructura diferente.