Die mit NGINX Plus R15 veröffentlichte Version des NGINX-JavaScript-Moduls kann jetzt Unteranforderungen ausgeben, was bedeutet, dass Anforderungen im JavaScript-Code initiiert werden können. Dadurch kann ein ganz neuer Satz von Anwendungsfällen adressiert werden.
Einer dieser Anwendungsfälle ist die Stapelverarbeitung von API-Anfragen, sodass eine einzelne API-Anfrage eines Clients in mehrere API-Anfragen an eine Reihe von Backend-Servern umgewandelt und die Antworten zu einer einzigen Antwort an den Client zusammengefasst werden können. In diesem Blog verwenden wir eine E-Commerce-Site als Beispiel – wenn der Kunde Informationen zu einem bestimmten Produkt anfordert, werden Unteranfragen an drei Back-End-Dienste gestellt: Katalog, Lager und Kundenrezensionen.
Dieser Beitrag baut auf dem Subrequest-Beispiel in der NGINX Plus R15 -Ankündigung auf, das zeigt, wie Subrequests verwendet werden, um dieselbe Anfrage an zwei Backend-Server zu senden und nur die erste Antwort an den Client zurückzugeben.
[ Herausgeber – Dieser Beitrag ist einer von mehreren, die Anwendungsfälle für das NGINX-JavaScript-Modul untersuchen. Eine vollständige Liste finden Sie unter Anwendungsfälle für das NGINX-JavaScript-Modul .
Der Beitrag wurde aktualisiert, um die Direktive js_import
zu verwenden, die die Direktive js_include
in NGINX Plus R23 und höher ersetzt. Weitere Informationen finden Sie in der Referenzdokumentation für das NGINX-JavaScript-Modul – der Abschnitt „Beispielkonfiguration“ zeigt die richtige Syntax für die NGINX-Konfiguration und JavaScript-Dateien. ]
Das Ziel dieses Beitrags besteht darin, funktionierende Beispiele für die einfache und unkomplizierte Batchverarbeitung von API-Anforderungen bereitzustellen. Die Beispiele erfüllen alle der folgenden Anforderungen:
GET
-Methode verwendet.Es werden zwei Arten von API-Anfragen unterstützt:
Beachten Sie, dass bei beiden Stilen zusätzliche Argumente in der Abfragezeichenfolge enthalten sein können.
Zusätzlich zur Verwendung der neuen Subrequest-Funktion von NGINX JavaScript nutzt diese Lösung die Schlüssel-Wert-Speicherfunktion von NGINX Plus, wodurch Konfigurationsänderungen dynamisch mit der NGINX Plus-API vorgenommen werden können.
Die folgenden Grafiken veranschaulichen die beiden unterstützten Anforderungsstile.
Anforderungsstil für letztes Element:
Abfragezeichenfolgen-Anforderungsstil:
In beiden Beispielen muss der Kunde Informationen zu einem Produkt aus dem Katalog, dem Lagerbestand und den Bewertungsdiensten abrufen. Es sendet eine Anfrage an NGINX Plus und übergibt die Artikelnummer entweder als Teil der URI oder in der Abfragezeichenfolge. Anschließend werden Anfragen an die drei Dienste gesendet und die Antworten zu einer einzigen Antwort an den Client zusammengefasst.
Damit dies mit NGINX Plus funktioniert, sind zwei Komponenten erforderlich: ein JavaScript-Programm und die NGINX Plus-Konfiguration .
Für jede Client-Anfrage wird die JavaScript-Funktion batchAPI()
aufgerufen. Es ruft die durch Kommas getrennte Liste der API-URIs aus dem Schlüssel-Wert-Speicher ab, durchläuft sie und stellt für jede eine Unteranforderung, wobei die Rückruffunktion done()
angegeben wird, um jede Antwort zu verarbeiten. Bei Anfragen im Stil des letzten Elements wird das letzte Element der URI, das in der NGINX-Variable $uri_suffix
gespeichert ist, als Abfragezeichenfolge jeder Unteranfrage zusammen mit allen anderen Abfragezeichenfolgenargumenten in der ursprünglichen Client-URI übergeben. Bei Anfragen im Stil der Abfragezeichenfolge wird die Abfragezeichenfolge aus den Clientanfragen als Abfragezeichenfolge jeder Unteranfrage übergeben.
Die Aufrufe erfolgen in der Reihenfolge, in der sie im Schlüssel-Wert-Speicher aufgeführt sind, sind jedoch asynchron, sodass die Antworten in beliebiger Reihenfolge zurückgegeben werden können. Die Antworten werden in der Reihenfolge ihres Eingangs zu einer Antwort an den Client zusammengefasst. Hier ist eine minimale Version des JavaScript-Programms:
Eine Version des JavaScript-Programms mit umfassenderer Fehlerbehandlung, Protokollierung und Kommentaren ist im GitHub Gist-Repository als batch-api.js verfügbar.
Die folgende NGINX Plus-Konfiguration implementiert die beiden oben besprochenen Anforderungsstile unter Verwendung einer Gruppe von Upstream-Servern. Der Einfachheit halber geht diese Konfiguration davon aus, dass die Upstream-Server einen Aufruf der Form /myapi/ service / item# (Formatvorlage des letzten Elements) in /myapi/service.php/?item=item# ( Formatvorlage der Abfragezeichenfolge) übersetzen können. Dabei handelt es sich um das „native“ URI-Format für PHP, die Sprache für unseren Beispielkatalog sowie für Inventar- und Überprüfungsdienste.
Eine umfangreichere NGINX Plus-Konfiguration, die die Übersetzung selbst durchführt, finden Sie weiter unten unter „Erweitern der NGINX-Konfiguration zum Übersetzen von URIs“ .
Schauen wir uns die Konfigurationsdatei Abschnitt für Abschnitt an und erklären, was jeder Teil macht:
Importieren Sie die JavaScript-Datei :
Definieren Sie einen Schlüssel-Wert-Speicher zur Speicherung der Liste der API-Anfragen, wobei das letzte Element der URI das Argument für das API-Programm identifiziert. Der Schlüssel verwendet die Variable $uri_prefix,
um den Teil der URI vor dem letzten / zu erfassen:
In NGINX Plus R16 und höher können Sie zwei zusätzliche Schlüssel-Wert-Funktionen nutzen:
keyval_zone
den Parameter timeout
hinzufügen. Um beispielsweise jeden Batch-URI täglich ablaufen zu lassen, fügen Sie timeout=1d
hinzu.keyval_zone“
den Synchronisierungsparameter
hinzufügen. In diesem Fall müssen Sie auch den Timeout-
Parameter mit einbeziehen.Anweisungen zum Einrichten der Synchronisierung für Schlüssel-Wert-Speicher finden Sie im NGINX Plus-Administratorhandbuch .
Definieren Sie einen anderen Schlüssel-Wert-Speicher für APIs, in denen das Argument in der Abfragezeichenfolge identifiziert wird. Hier erfasst der Schlüssel ( $uri
) die gesamte URI, ohne die Abfragezeichenfolge:
Definieren Sie zwei Maps, um die URI in zwei Teile aufzuteilen für APIs, die Anfragen akzeptieren, bei denen das Argument das letzte Element der URI ist. Die Variable $uri_prefix
erfasst die URI-Elemente vor dem letzten / und $uri_suffix
erfasst das letzte Element:
Definieren Sie die Upstream-Gruppe der API-Server (hier werden sie zusammen mit NGINX Plus auf localhost ausgeführt):
Definieren Sie den virtuellen Server , der Clientanforderungen und Unteranforderungen verarbeitet:
Definieren Sie einen Speicherort für die Verarbeitung von Clientanforderungen, die den Final‑Element‑Stil verwenden. Dies wird der batchAPI‑
Funktion angezeigt, indem die Variable $batch_api_arg_in_uri
auf on
gesetzt wird:
Definieren Sie einen Speicherort für die Verarbeitung von Clientanforderungen, die den Abfragezeichenfolgenstil verwenden. Dies wird der batchAPI
-Funktion angezeigt, indem die Variable $batch_api_arg_in_uri
auf off
gesetzt wird:
Definieren Sie den Speicherort, der die Unteranforderungen verarbeitet:
Aktivieren Sie die NGINX Plus-API , damit Daten im Schlüssel-Wert-Speicher verwaltet werden können:
Hier ist die vollständige Konfiguration:
Wir verwenden die Schlüssel-Wert-Speicherfunktion von NGINX Plus, um eingehende Clientanforderungen einer Reihe von auszuführenden API-Anforderungen zuzuordnen. Die Konfiguration im vorherigen Abschnitt definiert separate Schlüssel‑Wert‑Speicher für die beiden Anforderungsstile:
$uri_prefix
, die die Elemente vor dem letzten / der Anforderungs-URI erfasst.$uri
, die die vollständige Anforderungs-URI ohne die Abfragezeichenfolge erfasst.In beiden Schlüssel-Wert-Speichern ist der jedem Schlüssel zugeordnete Wert eine durch Kommas getrennte Liste von URIs, die zur Laufzeit in den Variablen „$batch_api“
oder „$batch_api2“
verfügbar gemacht werden.
Für Anfragen im Final‑Element‑Stil möchten wir eine Client‑Anfrage für /batch-api/product Anfragen an die drei Dienste /myapi/catalog , /myapi/inventory und /myapi/review zuordnen, sodass eine Anfrage für /batch-api/product/14286 Anfragen an /myapi/catalog/14286 , /myapi/product/14286 und /myapi/review/14286 ergibt.
Um diese Zuordnungen zum Schlüssel-Wert-Speicher der batch_api hinzuzufügen, senden wir die folgende Anfrage an die auf dem lokalen Computer ausgeführte NGINX Plus-Instanz:
$ curl -iX POST -d '{"/batch-api/product":"/myapi/catalog,/myapi/inventory,/myapi/review"}' http://localhost/api/3/http/keyvals/batch_api
Für die Anfragen im Abfragezeichenfolgenstil möchten wir eine Clientanfrage für /batch-api2/product Anfragen an die drei Dienste /myapi/catalog.php , /myapi/inventory.php und /myapi/review.php zuordnen, sodass eine Anfrage für /batch-api2/product?item=14286 Anfragen an /myapi/catalog?item=14286 , /myapi/product?item=14286 und /myapi/review?item=14286 ergibt.
Um diese Zuordnungen zum Schlüssel-Wert-Speicher batch_api2 hinzuzufügen, senden wir diese Anfrage:
$ curl -iX POST -d '{"/batch-api2/product":"/myapi/catalog.php,/myapi/inventory.php,/myapi/review.php"}' http://localhost/api/3/http/keyvals/batch_api2
Dieselben PHP-Seiten verarbeiten Anfragen, die in beiden Anfragestilen gestellt werden. Der Einfachheit halber gehen wir davon aus, dass die Backend-Server in der Lage sind, URIs im Stil des letzten Elements ( /myapi/ service / item# ) in URIs im Stil der Abfragezeichenfolge ( /myapi/ service .php?item= item# ) zu übersetzen. Es ist nicht erforderlich, URIs im Abfragezeichenfolgenstil zu übersetzen, da dies das „native“ URI-Format für PHP-Programme ist.
Alle Dienste geben eine Antwort im JSON-Format zurück, die den Dienstnamen und das Elementarargument enthält. Beispielsweise führt eine Anfrage nach /myapi/catalog.php?item=14286 zu der folgenden Antwort von catalog.php :
{"service":"Katalog","item":"14286"}
Obwohl die in diesen Beispielen verwendeten PHP-Programme den Dienstnamen in der Antwort enthalten, ist dies möglicherweise nicht bei allen Diensten der Fall. Um die Antworten den Diensten zuzuordnen, die sie generiert haben, schließt das JavaScript-Programm die URI in die aggregierte Antwort ein.
Beispielsweise lautet die aggregierte Antwort auf eine Anforderung für /batch-api/product/14286 wie folgt (die Reihenfolge der drei Komponentenantworten kann jedoch variieren):
[["/myapi/review/14286",{"service":"Rezension","item":"14286"}],["/myapi/inventory/14286",{"service":"Inventar","item":"14286"}],["/myapi/catalog/14286",{"service":"Katalog","item":"14286"}]]
Wie erwähnt, geht die oben besprochene minimale NGINX Plus-Konfiguration davon aus, dass die API-Server in der Lage sind, URIs im Format /myapi/ service / item# in /myapi/ service .php/?item= item# zu übersetzen. Wir können die Übersetzung auch in der NGINX Plus-Konfiguration implementieren, indem wir die folgenden Änderungen vornehmen.
Fügen Sie eine neue Upstream-Gruppe hinzu, um die Unteranforderungen zu empfangen:
Fügen Sie einen neuen virtuellen Server hinzu, um auf Anfragen zu warten, die von der Upstream-Gruppe der Dienste empfangen werden. Wenn Anfragen im Abfragezeichenfolgenstil empfangen werden, werden sie einfach an die Upstream-Gruppe „API_Servers“ weitergeleitet, da die URI bereits die Erweiterung .php hat. Wenn Anfragen im Final‑Element‑Stil empfangen werden, wird die URI so umgeschrieben, dass das letzte Element in der URI entfernt und in ein Abfragezeichenfolgenargument konvertiert wird:
Ändern Sie den Speicherort /myapi, um einen Proxy für die neue Upstream-Gruppe bereitzustellen:
Hier ist die vollständige Konfiguration:
Die Beispielprogramme in JavaScript und die Konfigurationen von NGINX Plus können an andere API-Stile angepasst werden. Wenn Sie jedoch alle Komponenten testen möchten, die zum Erstellen dieses Blogbeitrags verwendet wurden, stehen sie in unserem Gist-Repository auf GitHub zur Verfügung, einschließlich der NGINX-Unit-Konfiguration zum Bereitstellen der PHP-Seiten:
batch-api.js
katalog.php
inventar.php
bewertung.php
unit.config
Diese Beispiele zeigen, wie API-Anfragen gebündelt und dem Client eine aggregierte Antwort bereitgestellt werden. Der NGINX Plus-Schlüssel-Wert-Speicher ermöglicht es uns, die API-Anfragen dynamisch mit der NGINX Plus-API zu konfigurieren. API-Systeme unterscheiden sich in ihrer genauen Funktionsweise erheblich, daher können an diesem Beispiel viele Verbesserungen vorgenommen werden, um den Anforderungen einer bestimmten API gerecht zu werden.
Sie können mit dem Testen von NGINX JavaScript-Unteranforderungen mit NGINX Open Source beginnen. Wenn Sie jedoch die API-Batchverarbeitungsbeispiele ausprobieren oder andere Anwendungsfälle testen möchten, die die Vorteile der NGINX Plus-Funktionen wie den Schlüssel-Wert-Speicher und die NGINX Plus-API nutzen, fordern Sie eine kostenlose 30-Tage-Testversion an und beginnen Sie mit dem Experimentieren.
„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."