Traitement des requêtes par lots avec API Gateway
April 27, 2023
Le traitement par lots des requêtes est une technique puissante utilisée dans le développement web pour améliorer les performances des API. Elle permet aux développeurs de regrouper plusieurs requêtes API en un seul cycle de requête/réponse HTTP. En d'autres termes, une seule requête API d'un client peut être transformée en plusieurs requêtes API vers un ensemble de serveurs backend, et les réponses sont agrégées en une seule réponse au client. Cela peut réduire considérablement le nombre d'allers-retours entre le client et le serveur.
Dans cet article, nous explorerons comment implémenter le traitement par lots des requêtes dans Apache APISIX et examinerons quelques cas d'utilisation où cela peut être bénéfique.
Cela est similaire au modèle de Composition d'API largement appliqué dans l'architecture Microservices.
Pourquoi utiliser le traitement par lots des requêtes ?
Lorsqu'un client envoie plusieurs requêtes API à un serveur, chaque requête nécessite un cycle de requête/réponse HTTP séparé. Cela peut entraîner une latence accrue, une performance réduite et une charge serveur accrue. En regroupant plusieurs requêtes en une seule requête par lots, le nombre de cycles de requête/réponse HTTP peut être réduit, ce qui améliore les performances et réduit la latence.
Le traitement par lots des requêtes peut être particulièrement utile dans les scénarios où vous devez récupérer ou mettre à jour plusieurs enregistrements en une seule transaction, tels que :
- Récupérer plusieurs enregistrements d'une base de données
- Mettre à jour plusieurs enregistrements dans une base de données
- Exécuter plusieurs requêtes API pour accomplir une tâche
Exemples concrets de traitement par lots des requêtes
Exemple 1 :
Supposons que vous avez une application de médias sociaux qui affiche le fil d'actualité d'un utilisateur, comprenant des publications de ses amis et des pages qu'il suit. Pour remplir ce fil d'actualité, vous devez effectuer plusieurs requêtes API pour récupérer les données nécessaires, telles que :
- Récupérer une liste des amis de l'utilisateur et des pages qu'il suit.
- Pour chaque ami ou page, récupérer leurs publications récentes.
Dans une approche traditionnelle, vous effectueriez chacune de ces requêtes API séparément. D'abord, vous récupérez une liste des amis de l'utilisateur, puis dans une deuxième requête, vous obtenez les publications récentes pour chaque ami de l'utilisateur. Cela peut entraîner une latence accrue, surtout si l'utilisateur a un grand nombre d'amis et suit de nombreuses pages.
Exemple 2 :
Un autre exemple, vous avez une application mobile qui affiche une liste de produits que les utilisateurs peuvent parcourir. Pour remplir cette liste, vous devez effectuer plusieurs requêtes API pour récupérer les données des produits depuis un serveur distant, telles que :
- Récupérer une liste d'identifiants de produits.
- Pour chaque identifiant de produit, récupérer les détails du produit (nom, description, image, etc.)
Exemple 3 :
Imaginez que vous avez une application web de gestion de conférences où il y a plusieurs intervenants dans le système et vous souhaitez afficher les sessions et les sujets liés d'un intervenant sur une seule page web. Un service backend Conference API a deux points de terminaison différents /speaker/{speakerId}/sessions
et /speaker/{speakerId}/topics
pour exposer ces informations. Pour afficher à la fois les sessions et les sujets d'un seul intervenant, vous pouvez envoyer deux requêtes depuis l'application frontend, ce qui n'est pas une solution idéale. Au lieu de cela, vous pouvez utiliser une API Gateway pour regrouper toutes ces requêtes en une seule requête HTTP, comme expliqué dans la section suivante.
Traitement par lots des requêtes avec Apache APISIX API Gateway
Pour implémenter le traitement par lots des requêtes dans APISIX, vous pouvez utiliser le plugin batch-requests. Ce plugin vous permet de définir un ensemble de requêtes API dans une seule charge utile de requête HTTP POST
. Chaque requête peut avoir sa propre méthode HTTP, chemin d'URL, ensemble d'en-têtes et charge utile. Voir ci-dessous un exemple de commande curl pour l'exemple 3 (requêtes 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"
}
]
}'
Lorsqu'une requête par lots est reçue par APISIX, le plugin batch-requests analysera la charge utile et exécutera chaque requête du lot en parallèle. Le plugin agrègera également les réponses de chaque requête et les retournera dans une seule réponse HTTP au client. Voir la section de démonstration suivante pour apprendre comment y parvenir étape par étape.
Démonstration du plugin batch-requests
Avant de pouvoir utiliser le plugin batch-requests, vous devrez installer Apache APISIX.
Prérequis
- Docker est utilisé pour installer etcd et APISIX conteneurisés.
- curl est utilisé pour envoyer des requêtes à l'API Admin d'APISIX. Vous pouvez également utiliser des outils simples comme Postman pour interagir avec l'API.
APISIX peut être facilement installé et démarré avec le script de démarrage rapide suivant :
curl -sL <https://run.api7.ai/apisix/quickstart> | sh
Configurer le service backend (upstream)
Vous devrez configurer le service backend pour Conference API vers lequel vous souhaitez router les requêtes. Cela peut être fait en ajoutant un serveur upstream dans Apache APISIX via l'API Admin.
curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -X PUT -d '
{
"name": "Conferences API upstream",
"desc": "Register Conferences API as the upstream",
"type": "roundrobin",
"scheme": "https",
"nodes": {
"conferenceapi.azurewebsites.net:443": 1
}
}'
Créer une Route pour l'API de traitement par lots
Nous devons créer une nouvelle route qui intercepte les requêtes vers /speaker
et expose un point de terminaison virtuel public pour le traitement par lots en utilisant le 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"
}
}
}'
Créer une Route pour les points de terminaison des sujets et sessions de l'intervenant
Ensuite, nous créons une autre route pour les points de terminaison des sujets et sessions de l'intervenant (/speaker/*/topics
et /speaker/*/sessions
) afin que les requêtes individuelles extraites par la passerelle API des requêtes par lots pour récupérer les sujets ou sessions de l'intervenant soient redirigées vers les points de terminaison responsables de Conference API et nous référençons le service upstream existant.
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"
}'
Vous remarquerez peut-être que nous utilisons un autre plugin proxy-rewrite et spécifions implicitement l'adresse hôte pour Conference API. Sinon, la passerelle API peut effectuer une conversion DNS et demander Conference API par son adresse IP.
Tester le traitement par lots des requêtes
Voici un exemple d'utilisation du plugin batch-requests dans 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"
}
]
}'
Dans cet exemple, la route est définie pour le point de terminaison /speaker
, qui prend en charge le traitement par lots des requêtes via le plugin batch-requests. Le plugin est configuré avec un ensemble de deux requêtes, chacune récupérant un enregistrement d'intervenant par ID avec ses sujets et sessions. Si vous exécutez cette commande, vous obtiendrez une réponse fusionnée de la passerelle API :
[
{
"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"
}
]
La taille maximale d'une requête par lots est limitée par la passerelle API. Vous pouvez consulter la documentation de la passerelle API pour les limites actuelles et la configuration du délai d'attente des requêtes.
Points à retenir
- Le traitement par lots des requêtes avec une passerelle API peut être une technique utile pour améliorer les performances de votre API.
- Apache APISIX fournit un plugin appelé
batch-requests
qui permet aux développeurs d'implémenter facilement le traitement par lots des requêtes.
Prochaines étapes
Avec une passerelle API, il est également possible de fournir une forme d'agrégation personnalisée dans les données de réponse à vos utilisateurs. Vous pouvez utiliser le plugin serverless-function pour exécuter du code personnalisé et fusionner la réponse des services backend et la retourner au consommateur de l'API dans une structure différente.