La version du module JavaScript NGINX publiée avec NGINX Plus R15 peut désormais émettre des sous-requêtes, ce qui signifie que les requêtes peuvent être initiées dans le code JavaScript. Cela permet de traiter un tout nouvel ensemble de cas d’utilisation.
L’un de ces cas d’utilisation consiste à regrouper les demandes d’API afin qu’une seule demande d’API d’un client puisse être transformée en plusieurs demandes d’API adressées à un ensemble de serveurs principaux et que les réponses soient agrégées en une seule réponse adressée au client. Dans ce blog, nous utilisons un site de commerce électronique comme exemple. Lorsque le client demande des informations sur un produit particulier, des sous-requêtes sont adressées à trois services back-end : catalogue, inventaire et avis clients.
Cet article s'appuie sur l'exemple de sous-requête de l' annonce NGINX Plus R15 , qui montre comment utiliser des sous-requêtes pour envoyer la même requête à deux serveurs principaux et renvoyer uniquement la première réponse au client.
[ Éditeur – Cet article est l’un des nombreux articles qui explorent les cas d’utilisation du module JavaScript NGINX. Pour une liste complète, voir Cas d'utilisation du module JavaScript NGINX .
L'article est mis à jour pour utiliser la directive js_import
, qui remplace la directive js_include
dans NGINX Plus R23 et versions ultérieures. Pour plus d’informations, consultez la documentation de référence du module JavaScript NGINX – la section Exemple de configuration montre la syntaxe correcte pour la configuration NGINX et les fichiers JavaScript. ]
L’objectif de cet article est de fournir des exemples fonctionnels de traitement par lots de requêtes API qui sont simples et directs. Les exemples répondent à toutes les exigences suivantes :
GET
est utilisée pour toutes les requêtes.Deux styles de requêtes API sont pris en charge :
Notez qu'avec l'un ou l'autre style, il peut y avoir des arguments supplémentaires dans la chaîne de requête.
En plus d'utiliser la nouvelle fonctionnalité de sous-requête de NGINX JavaScript, cette solution utilise la fonctionnalité de magasin de valeurs clés de NGINX Plus, permettant d'effectuer des modifications de configuration de manière dynamique avec l' API NGINX Plus .
Les graphiques suivants illustrent les deux styles de demande pris en charge.
Style de demande d'élément final :
Style de requête de chaîne de requête :
Dans les deux exemples, le client doit obtenir des informations sur un produit à partir du catalogue, de l’inventaire et des services d’évaluation. Il envoie une requête à NGINX Plus, en transmettant le numéro d'élément dans le cadre de l'URI ou dans la chaîne de requête. Les demandes sont ensuite envoyées aux trois services et les réponses sont agrégées en une seule réponse au client.
Deux composants sont nécessaires pour que cela fonctionne avec NGINX Plus : un programme JavaScript et la configuration NGINX Plus .
La fonction JavaScript batchAPI()
est appelée pour chaque demande client. Il obtient la liste séparée par des virgules des URI d'API du magasin clé-valeur et les parcourt, en créant une sous-requête pour chacun et en spécifiant la fonction de rappel done()
pour traiter chaque réponse. Pour les requêtes de type élément final, le dernier élément de l'URI, stocké dans la variable NGINX $uri_suffix
, est transmis comme chaîne de requête de chaque sous-requête, avec tous les autres arguments de chaîne de requête dans l'URI client d'origine. Pour les requêtes de type chaîne de requête, la chaîne de requête des requêtes client est transmise comme chaîne de requête de chaque sous-requête.
Les appels sont effectués dans l’ordre dans lequel ils sont répertoriés dans le magasin clé-valeur, mais sont asynchrones, de sorte que les réponses peuvent revenir dans n’importe quel ordre. Les réponses sont regroupées en une seule réponse adressée au client dans l’ordre dans lequel elles sont reçues. Voici une version minimale du programme JavaScript :
Une version du programme JavaScript avec une gestion des erreurs, une journalisation et des commentaires plus étendus est disponible dans le référentiel GitHub Gist sous le nom batch-api.js .
La configuration NGINX Plus suivante implémente les deux styles de requête décrits ci-dessus, en utilisant un groupe de serveurs en amont. Pour simplifier les choses, cette configuration suppose que les serveurs en amont sont capables de traduire un appel de la forme /myapi/ service / item# (style élément final) en /myapi/ service .php/?item= item# (style chaîne de requête), qui est le format d'URI « natif » pour PHP, le langage de nos exemples de services de catalogue, d'inventaire et de révision.
Pour une configuration NGINX Plus plus étendue qui effectue la traduction elle-même, voir Extension de la configuration NGINX pour traduire les URI ci-dessous.
Examinons le fichier de configuration section par section et expliquons ce que fait chaque partie :
Importer le fichier JavaScript :
Définissez un magasin clé-valeur pour contenir la liste des requêtes API où le dernier élément de l’URI identifie l’argument du programme API. La clé utilise la variable $uri_prefix
pour capturer la partie de l'URI avant le dernier / :
Dans NGINX Plus R16 et versions ultérieures, vous pouvez profiter de deux fonctionnalités clé-valeur supplémentaires :
timeout
à la directive keyval_zone
. Par exemple, pour que chaque URI groupé expire quotidiennement, ajoutez timeout=1d
.sync
à la directive keyval_zone
. Vous devez également inclure le paramètre timeout
dans ce cas.Pour obtenir des instructions sur la configuration de la synchronisation pour les magasins clé-valeur, consultez le Guide d'administration NGINX Plus .
Définissez un autre magasin clé-valeur pour les API où l’argument est identifié dans la chaîne de requête. Ici, la clé ( $uri
) capture l'intégralité de l'URI, sans inclure la chaîne de requête :
Définissez deux cartes pour diviser l'URI en deux parties pour les API qui acceptent les requêtes où l'argument est le dernier élément de l'URI. La variable $uri_prefix
capture les éléments d'URI avant le dernier / et $uri_suffix
capture l'élément final :
Définissez le groupe en amont des serveurs API (ici, ils s'exécutent sur localhost avec NGINX Plus) :
Définissez le serveur virtuel qui gère les requêtes et sous-requêtes des clients :
Définissez un emplacement pour gérer les demandes client qui utilisent le style d'élément final, qui est indiqué à la fonction batchAPI
en définissant la variable $batch_api_arg_in_uri
sur on
:
Définissez un emplacement pour gérer les requêtes client qui utilisent le style de chaîne de requête, qui est indiqué à la fonction batchAPI
en définissant la variable $batch_api_arg_in_uri
sur off
:
Définissez l'emplacement qui gère les sous-requêtes :
Activez l' API NGINX Plus pour que les données puissent être conservées dans le magasin clé-valeur :
Voici la configuration complète :
Nous utilisons la fonctionnalité de magasin de clés-valeurs NGINX Plus pour mapper les demandes client entrantes à un ensemble de demandes API à exécuter. La configuration de la section précédente définit des magasins de clés-valeurs distincts pour les deux styles de requête :
$uri_prefix
, qui capture les éléments avant le / final de l’URI de la demande.$uri
, qui capture l'URI de la requête complète sans la chaîne de requête.Dans les deux magasins clé-valeur, la valeur associée à chaque clé est une liste séparée par des virgules d’URI qui sont mises à disposition au moment de l’exécution dans les variables $batch_api
ou $batch_api2
.
Pour les requêtes de style élément final, nous souhaitons mapper une requête client pour /batch-api/product aux requêtes adressées aux trois services /myapi/catalog , /myapi/inventory et /myapi/review , de sorte qu'une requête pour /batch-api/product/14286 génère des requêtes adressées à /myapi/catalog/14286 , /myapi/product/14286 et /myapi/review/14286 .
Pour ajouter ces mappages au magasin clé-valeur batch_api , nous envoyons la requête suivante à l’instance NGINX Plus exécutée sur la machine locale :
$ curl -iX POST -d '{"/batch-api/product":"/myapi/catalog,/myapi/inventory,/myapi/review"}' http://localhost/api/3/http/keyvals/batch_api
Pour les requêtes de style chaîne de requête, nous souhaitons mapper une requête client pour /batch-api2/product aux requêtes adressées aux trois services /myapi/catalog.php , /myapi/inventory.php et /myapi/review.php , de sorte qu'une requête pour /batch-api2/product?item=14286 génère des requêtes adressées à /myapi/catalog?item=14286 , /myapi/product?item=14286 et /myapi/review?item=14286 .
Pour ajouter ces mappages au magasin clé-valeur batch_api2 , nous envoyons cette requête :
$ curl -iX POST -d '{"/batch-api2/product":"/myapi/catalog.php,/myapi/inventory.php,/myapi/review.php"}' http://localhost/api/3/http/keyvals/batch_api2
Les mêmes pages PHP gèrent les requêtes effectuées dans les deux styles de requête. Pour plus de simplicité, nous supposons que les serveurs principaux sont capables de traduire les URI de style élément final ( /myapi/ service / item# ) en URI de style chaîne de requête ( /myapi/ service .php?item= item# ). Il n’est pas nécessaire de traduire les URI de style chaîne de requête, car il s’agit du format URI « natif » pour les programmes PHP.
Tous les services renvoient une réponse au format JSON qui inclut le nom du service et l’argument de l’élément. Par exemple, une requête pour /myapi/catalog.php?item=14286 génère la réponse suivante de catalog.php :
{"service":"Catalogue","item":"14286"}
Bien que les programmes PHP utilisés dans ces exemples incluent le nom du service dans la réponse, cela peut ne pas être le cas pour tous les services. Pour aider à faire correspondre les réponses aux services qui les ont générées, le programme JavaScript inclut l'URI dans la réponse agrégée.
Par exemple, la réponse agrégée pour une demande pour /batch-api/product/14286 est la suivante (bien que l'ordre des trois réponses des composants puisse varier) :
[["/myapi/review/14286",{"service":"Avis","item":"14286"}],["/myapi/inventory/14286",{"service":"Inventaire","item":"14286"}],["/myapi/catalog/14286",{"service":"Catalogue","item":"14286"}]]
Comme mentionné, la configuration minimale de NGINX Plus décrite ci-dessus suppose que les serveurs API sont capables de traduire les URI au format /myapi/ service / item# en /myapi/ service .php/?item= item# . Nous pouvons également implémenter la traduction dans la configuration NGINX Plus en apportant les modifications suivantes.
Ajoutez un nouveau groupe en amont pour recevoir les sous-requêtes :
Ajoutez un nouveau serveur virtuel pour écouter les requêtes reçues par le groupe de services en amont. Lorsque des requêtes de style chaîne de requête sont reçues, elles sont simplement transmises au groupe en amont api_servers car l'URI possède déjà l'extension .php . Lorsque des demandes de style d’élément final sont reçues, l’URI est réécrit de sorte que le dernier élément de l’URI soit supprimé et converti en argument de chaîne de requête :
Modifiez l' emplacement /myapi pour qu'il serve de proxy au nouveau groupe en amont :
Voici la configuration complète :
Les exemples de programmes JavaScript et les configurations NGINX Plus peuvent être adaptés à d'autres styles d'API, mais si vous souhaitez tester en utilisant tous les composants utilisés pour créer cet article de blog, ils sont disponibles dans notre référentiel Gist sur GitHub, y compris la configuration de l'unité NGINX pour diffuser les pages PHP :
batch-api.js
catalogue.php
inventaire.php
avis.php
unité.config
Ces exemples montrent comment regrouper les requêtes API et fournir une réponse agrégée au client. Le magasin de clés-valeurs NGINX Plus nous permet de configurer les requêtes API de manière dynamique avec l' API NGINX Plus . Les systèmes d'API varient considérablement dans leurs opérations exactes, de sorte que de nombreuses améliorations peuvent être apportées à cet exemple pour répondre aux besoins d'une API particulière.
Vous pouvez commencer à tester les sous-requêtes JavaScript NGINX avec NGINX Open Source , mais si vous souhaitez essayer les exemples de traitement par lots d'API ou tester d'autres cas d'utilisation qui tirent parti des fonctionnalités NGINX Plus comme le magasin clé-valeur et l'API NGINX Plus , demandez un essai gratuit de 30 jours et commencez à expérimenter.
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."