Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Tipp
Dieser Inhalt ist ein Auszug aus dem eBook .NET Microservices Architecture for Containerized .NET Applications, verfügbar auf .NET Docs oder als kostenlose herunterladbare PDF, die offline gelesen werden kann.
In einer Microservices-Architektur macht jeder Microservice eine Reihe von (in der Regel) fein abgestimmten Endpunkten verfügbar. Diese Tatsache kann sich auf die Client-zu-Microservice-Kommunikation auswirken, wie in diesem Abschnitt erläutert.
Direkte Client-zu-Microservice-Kommunikation
Ein möglicher Ansatz besteht darin, eine direkte Client-zu-Microservice-Kommunikationsarchitektur zu verwenden. Bei diesem Ansatz kann eine Client-App Anforderungen direkt an einige der Microservices senden, wie in Abbildung 4-12 dargestellt.
Abbildung 4-12. Verwenden einer direkten Client-zu-Microservice-Kommunikationsarchitektur
Bei diesem Ansatz verfügt jeder Microservice über einen öffentlichen Endpunkt, manchmal mit einem anderen TCP-Port für jeden Microservice. Ein Beispiel für eine URL für einen bestimmten Dienst könnte die folgende URL in Azure sein:
http://eshoponcontainers.westus.cloudapp.azure.com:88/
In einer Produktionsumgebung, die auf einem Cluster basiert, würde diese URL dem lastenausgleichsmodul zugeordnet, das im Cluster verwendet wird, wodurch wiederum die Anforderungen über die Microservices verteilt werden. In Produktionsumgebungen könnten Sie über einen Application Delivery Controller (ADC) wie Azure Application Gateway zwischen Ihren Microservices und dem Internet verfügen. Diese Ebene fungiert als transparente Ebene, die nicht nur einen Lastenausgleich durchführt, sondern Ihre Dienste durch die Bereitstellung von SSL-Beendigung sichert. Dieser Ansatz verbessert die Auslastung Ihrer Hosts durch das Entladen cpuintensiver SSL-Beendigung und anderer Routingaufgaben an das Azure-Anwendungsgateway. In jedem Fall sind ein Lastenausgleichsmodul und ADC aus sicht einer logischen Anwendungsarchitektur transparent.
Eine direkte Client-zu-Microservice-Kommunikationsarchitektur könnte für eine kleine mikroservicebasierte Anwendung gut genug sein, insbesondere, wenn die Client-App eine serverseitige Webanwendung wie eine ASP.NET MVC-App ist. Wenn Sie jedoch große und komplexe Mikroservice-basierte Anwendungen erstellen (z. B. bei der Behandlung von Dutzenden von Microservice-Typen), und insbesondere, wenn es sich bei client-Apps um mobile Remote-Apps oder SPA-Webanwendungen handelt, sieht dieser Ansatz ein paar Probleme auf.
Berücksichtigen Sie die folgenden Fragen beim Entwickeln einer großen Anwendung basierend auf Microservices:
- Wie können Client-Apps die Anzahl der Anforderungen an das Back-End minimieren und die Chatty-Kommunikation mit mehreren Microservices reduzieren?
Wenn zum Erstellen einer einzigen Benutzeroberflächenanzeige mit mehreren Microservices interagiert wird, steigt die Anzahl von Roundtrips im Internet. Dieser Ansatz erhöht die Latenz und Komplexität auf der Ui-Seite. Im Idealfall sollten Antworten effizient auf der Serverseite aggregiert werden. Dieser Ansatz verringert die Latenz, da mehrere Datenteile parallel zurückkommen und einige UI Daten anzeigen können, sobald sie bereit sind.
- Wie können Sie übergreifende Bedenken wie Autorisierung, Datentransformationen und dynamisches Senden von Anforderungen behandeln?
Die Implementierung von Sicherheitsaspekten und übergreifenden Belangen wie Autorisierung für jeden Microservice kann erhebliche Entwicklungsanstrengungen erfordern. Ein möglicher Ansatz besteht darin, diese Dienste innerhalb des Docker-Hosts oder internen Clusters zu verwenden, um den direkten Zugriff von außen auf sie einzuschränken und diese grenzüberschreitenden Bedenken an einem zentralen Ort zu implementieren, z. B. ein API-Gateway.
- Wie können Client-Apps mit Diensten kommunizieren, die nicht internetfreundliche Protokolle verwenden?
Protokolle, die auf serverseitiger Seite (z. B. AMQP- oder Binärprotokolle) verwendet werden, werden in Client-Apps nicht unterstützt. Daher müssen Anforderungen über Protokolle wie HTTP/HTTPS ausgeführt und anschließend in die anderen Protokolle übersetzt werden. Ein Man-in-the-Middle-Ansatz kann in dieser Situation helfen.
- Wie können Sie eine Fassade speziell für mobile Apps gestalten?
Die API mehrerer Microservices ist möglicherweise nicht gut für die Anforderungen verschiedener Clientanwendungen ausgelegt. Beispielsweise unterscheiden sich die Anforderungen einer mobilen App möglicherweise von den Anforderungen einer Web-App. Für mobile Apps müssen Sie möglicherweise noch weiter optimieren, damit Datenantworten effizienter werden können. Sie können diese Funktionalität ausführen, indem Sie Daten aus mehreren Microservices aggregieren und eine einzelne Datenmenge zurückgeben und manchmal alle Daten in der Antwort beseitigen, die von der mobilen App nicht benötigt wird. Und natürlich können Sie diese Daten komprimieren. Auch hier kann eine Fassade oder API zwischen der mobilen App und den Microservices für dieses Szenario praktisch sein.
Gründe für die Verwendung von API-Gateways anstelle der direkten Client-zu-Microservice-Kommunikation
In einer Microservices-Architektur müssen die Client-Apps in der Regel Funktionen von mehr als einem Microservice nutzen. Wenn dieser Verbrauch direkt ausgeführt wird, muss der Client mehrere Aufrufe an Microservice-Endpunkte verarbeiten. Was geschieht, wenn sich die Anwendung weiterentwickelt und neue Microservices eingeführt werden oder vorhandene Microservices aktualisiert werden? Wenn Ihre Anwendung über viele Microservices verfügt, kann die Behandlung so vieler Endpunkte aus den Client-Apps ein Albtraum sein. Da die Client-App mit diesen internen Endpunkten gekoppelt wäre, kann die Entwicklung der Microservices in Zukunft zu hohen Auswirkungen für die Client-Apps führen.
Daher kann eine Vermittlungsebene (Gateway) für mikroservicebasierte Anwendungen nützlich sein. Wenn Sie nicht über API-Gateways verfügen, müssen die Client-Apps Anforderungen direkt an die Microservices senden und Probleme verursachen, z. B. die folgenden Probleme:
Kopplung: Ohne das API-Gatewaymuster werden die Client-Apps mit den internen Microservices gekoppelt. Die Client-Apps müssen wissen, wie die verschiedenen Bereiche der Anwendung in Microservices dekompiliert werden. Wenn die internen Microservices weiterentwickelt und umgestaltet werden, kann dies aufgrund der direkten Verweise auf diese Microservices zu Breaking Changes bei den Client-Apps führen, was sich auf die Wartung auswirken kann. Client-Apps müssen häufig aktualisiert werden, wodurch die Lösung schwieriger weiterentwickelt werden kann.
Zu viele Roundtrips: Eine einzelne Seite/ein Bildschirm in der Client-App erfordert möglicherweise mehrere Aufrufe an mehrere Dienste. Dieser Ansatz kann zu mehreren Netzwerk-Roundtrips zwischen dem Client und dem Server führen und eine erhebliche Latenz hinzufügen. Aggregation, die auf einer Mittleren Ebene behandelt wird, könnte die Leistung und Benutzererfahrung für die Client-App verbessern.
Sicherheitsprobleme: Ohne gateways müssen alle Microservices der "externen Welt" offengelegt werden, wodurch die Angriffsfläche größer ist als wenn Sie interne Microservices ausblenden, die nicht direkt von den Client-Apps verwendet werden. Je kleiner die Angriffsfläche ist, desto sicherer kann Ihre Anwendung sein.
Grenzüberschreitende Bedenken: Jeder öffentlich veröffentlichte Microservice muss Bedenken wie Autorisierung und SSL behandeln. In vielen Fällen könnten diese Bedenken in einer einzigen Ebene behandelt werden, sodass die internen Microservices vereinfacht werden.
Was ist das API-Gatewaymuster?
Wenn Sie große oder komplexe mikroservicebasierte Anwendungen mit mehreren Client-Apps entwerfen und erstellen, kann ein guter Ansatz ein API-Gateway sein. Dieses Muster ist ein Dienst, der einen einstiegspunkt für bestimmte Gruppen von Microservices bereitstellt. Es ähnelt dem Fassadenmuster aus objektorientiertem Design, aber in diesem Fall ist es Teil eines verteilten Systems. Das API-Gatewaymuster wird manchmal auch als "Back-End für Frontend" (BFF) bezeichnet, da Sie es erstellen, während Sie über die Anforderungen der Client-App nachdenken.
Daher befindet sich das API-Gateway zwischen den Client-Apps und den Microservices. Sie fungiert als Reverse-Proxy und leitet Anforderungen von Clients an Dienste weiter. Sie kann auch andere querschnittsübergreifende Features wie Authentifizierung, SSL-Beendigung und Cache bereitstellen.
Abbildung 4-13 zeigt, wie ein benutzerdefiniertes API-Gateway in eine vereinfachte microservicebasierte Architektur mit nur wenigen Microservices passen kann.
Abbildung 4-13. Verwenden eines API-Gateways, das als benutzerdefinierter Dienst implementiert ist
Apps stellen eine Verbindung mit einem einzelnen Endpunkt her, dem API-Gateway, das für die Weiterleitung von Anforderungen an einzelne Microservices konfiguriert ist. In diesem Beispiel würde das API-Gateway als benutzerdefinierter ASP.NET Core WebHost-Dienst implementiert, der als Container ausgeführt wird.
Es ist wichtig hervorzuheben, dass in diesem Diagramm ein einzelner benutzerdefinierter API-Gateway-Dienst für mehrere unterschiedliche Client-Apps verwendet wird. Dies kann ein wichtiges Risiko sein, da Ihr API-Gatewaydienst aufgrund vieler unterschiedlicher Anforderungen von den Client-Apps wächst und sich weiterentwickeln wird. Schließlich wird es aufgrund dieser unterschiedlichen Bedürfnisse überladen und im Wesentlichen könnte es ähnlich wie eine monolithische Anwendung oder ein monolithischer Dienst sein. Deshalb wird dringend empfohlen, das API-Gateway in mehrere Dienste oder mehrere kleinere API-Gateways aufzuteilen, z. B. einen pro Client-App-Formfaktortyp.
Sie müssen beim Implementieren des API-Gatewaymusters vorsichtig sein. In der Regel empfiehlt es sich nicht, ein einzelnes API-Gateway zum Aggregieren aller internen Microservices Ihrer Anwendung zu verwenden. Wenn dies der Fall ist, handelt es sich um einen monolithischen Aggregator oder Orchestrator und verletzt die Mikroserviceautonomie durch Kopplung aller Microservices.
Daher sollten die API-Gateways basierend auf Geschäftsgrenzen und den Client-Apps getrennt werden und nicht als einzelner Aggregator für alle internen Microservices fungieren.
Wenn Sie die API-Gatewayebene in mehrere API-Gateways aufteilen und Ihre Anwendung über mehrere Client-Apps verfügt, kann dies der Hauptfokus bei der Identifizierung unterschiedlicher API-Gatewaytypen sein. Auf diese Weise können Sie für jede Client-App eine angepasste Fassade bereitstellen, die deren spezifischen Anforderungen gerecht wird. Dieser Fall ist ein Muster namens "Back-End für Frontend" (BFF), in dem jedes API-Gateway eine andere API bereitstellen kann, die auf jeden Client-App-Typ zugeschnitten ist, möglicherweise sogar basierend auf dem Clientformfaktor, indem spezifischer Adaptercode implementiert wird, der unter mehreren internen Microservices aufruft, wie in der folgenden Abbildung dargestellt:
Abbildung 4-13.1. Verwenden mehrerer benutzerdefinierter API-Gateways
Abbildung 4-13.1 zeigt API-Gateways, die nach Clienttyp getrennt sind; eine für mobile Clients und eine für Webclients. Eine herkömmliche Web-App stellt eine Verbindung mit einem MVC-Microservice dar, der das Web-API-Gateway verwendet. Das Beispiel zeigt eine vereinfachte Architektur mit mehreren feinkörnigen API-Gateways. In diesem Fall basieren die für jedes API-Gateway identifizierten Grenzen ausschließlich auf dem Muster "Back-End für Frontend" (BFF), daher basierend auf der api, die pro Client-App benötigt wird. Aber bei größeren Anwendungen sollten Sie auch weitergehen und andere auf Geschäftsgrenzen basierende API-Gateways als zweiten Entwurfsschwerpunkt erstellen.
Hauptfeatures im API-Gatewaymuster
Ein API-Gateway kann mehrere Features bieten. Je nach Produkt bietet es möglicherweise umfangreichere oder einfachere Features, aber die wichtigsten und grundlegenden Features für jedes API-Gateway sind die folgenden Entwurfsmuster:
Reverse-Proxy- oder Gateway-Routing. Das API-Gateway bietet einen Reverse-Proxy zum Weiterleiten oder Umleiten von Anforderungen (Schicht-7-Routing, in der Regel HTTP-Anforderungen) an die Endpunkte der internen Mikroservices. Das Gateway stellt einen einzelnen Endpunkt oder eine url für die Client-Apps bereit und ordnet die Anforderungen dann intern einer Gruppe interner Microservices zu. Dieses Routingfeature hilft dabei, die Client-Apps von den Microservices zu entkoppeln, aber es ist auch praktisch, wenn sie eine monolithische API modernisieren, indem Sie das API-Gateway zwischen der monolithischen API und den Client-Apps platzieren, dann können Sie neue APIs als neue Microservices hinzufügen, während Sie weiterhin die ältere monolithische API verwenden, bis sie in zukunft in viele Microservices aufgeteilt wird. Aufgrund des API-Gateways werden die Client-Apps nicht bemerken, wenn die verwendeten APIs als interne Microservices oder eine monolithische API implementiert werden und wichtiger ist, wenn die monolithische API aufgrund des API-Gateway-Routings in Mikroservices weiterentwickelt und umgestaltet wird, werden Client-Apps mit keiner URI-Änderung beeinträchtigt.
Weitere Informationen finden Sie unter Gateway-Routing-Muster.
Aggregierung von Anforderungen. Im Rahmen des Gatewaymusters können Sie mehrere Clientanforderungen (in der Regel HTTP-Anforderungen) für mehrere interne Microservices in einer einzigen Clientanforderung aggregieren. Dieses Muster ist besonders praktisch, wenn eine Clientseite/ein Bildschirm Informationen von mehreren Microservices benötigt. Bei diesem Ansatz sendet die Client-App eine einzelne Anforderung an das API-Gateway, die mehrere Anforderungen an die internen Microservices sendet und dann die Ergebnisse aggregiert und alles an die Client-App zurücksendet. Der Hauptvorteil und das Ziel dieses Entwurfsmusters besteht darin, die Chattigkeit zwischen den Client-Apps und der Back-End-API zu reduzieren, was besonders wichtig für Remote-Apps außerhalb des Rechenzentrums ist, in dem sich die Microservices befinden, z. B. mobile Apps oder Anforderungen von SPA-Apps, die aus JavaScript stammen, in Client-Remotebrowsern. Bei regulären Web-Apps, die die Anforderungen in der Serverumgebung ausführen (z. B. eine ASP.NET Core MVC-Web-App), ist dieses Muster nicht so wichtig, da die Latenz in der Serverumgebung deutlich geringer ist als bei Remoteclient-Apps.
Je nach verwendeter API-Gateway-Produkt kann diese Aggregation ausgeführt werden. In vielen Fällen ist es jedoch flexibler, Aggregations-Microservices im Bereich des API-Gateways zu erstellen, sodass Sie die Aggregation im Code definieren (d. h. C#-Code):
Weitere Informationen finden Sie unter Gateway-Aggregationsmuster.
Übergreifende Aspekte oder Gatewayabladung. Abhängig von den Features, die von den einzelnen API-Gateway-Produkten angeboten werden, können Sie Funktionen von einzelnen Microservices auf das Gateway auslagern, wodurch die Implementierung jedes Microservice vereinfacht wird, indem sie übergreifende Bedenken in einer Ebene konsolidieren. Dieser Ansatz eignet sich besonders für spezielle Features, die komplex sein können, um in jedem internen Microservice ordnungsgemäß zu implementieren, z. B. die folgenden Funktionen:
- Authentifizierung und Autorisierung
- Integration der Serviceerkennung
- Zwischenspeichern von Antworten
- Wiederholungsrichtlinien, Schaltschalter und QoS
- Ratenbegrenzung und -drosselung
- Lastverteilung
- Protokollierung, Ablaufverfolgung, Korrelation
- Header, Abfragezeichenfolgen und Anspruchstransformation
- Setzen von IP-Adressen auf die Positivliste
Weitere Informationen finden Sie unter Muster „Gatewayabladung“.
Verwenden von Produkten mit API-Gateway-Funktionen
Je nach Implementierung können viele weitere übergreifende Themen von den API-Gateway-Produkten angeboten werden. Wir werden an dieser Stelle untersuchen:
Azure-API-Verwaltung
Azure API Management (wie in Abbildung 4-14 dargestellt) löst nicht nur Ihre API-Gatewayanforderungen, sondern bietet Features wie das Sammeln von Erkenntnissen aus Ihren APIs. Wenn Sie eine API-Verwaltungslösung verwenden, ist ein API-Gateway nur eine Komponente innerhalb dieser vollständigen API-Verwaltungslösung.
Abbildung 4-14. Verwenden der Azure-API-Verwaltung für Ihr API-Gateway
Azure API Management löst sowohl Ihre API-Gateway- als auch Verwaltungsanforderungen wie Protokollierung, Sicherheit, Metering usw. In diesem Fall ist bei Verwendung eines Produkts wie Azure API Management die Tatsache, dass Sie möglicherweise über ein einzelnes API-Gateway verfügen, nicht so riskant, da diese Arten von API-Gateways "dünner" sind, was bedeutet, dass Sie keinen benutzerdefinierten C#-Code implementieren, der sich zu einer monolithischen Komponente entwickeln könnte.
Die API-Gateway-Produkte funktionieren in der Regel wie ein Reverseproxy für die eingehende Kommunikation, bei der Sie nicht nur APIs aus den internen Microservices filtern, sondern auch die Autorisierung auf die veröffentlichten APIs in dieser Einzel-Ebene anwenden können.
Die erkenntnisse, die von einem API-Verwaltungssystem zur Verfügung stehen, helfen Ihnen zu verstehen, wie Ihre APIs verwendet werden und wie sie funktionieren. Sie führen diese Aktivität aus, indem Sie nahezu Echtzeitanalyseberichte anzeigen und Trends identifizieren, die sich auf Ihr Unternehmen auswirken könnten. Darüber hinaus können Sie Protokolle zu Anforderungs- und Antwortaktivitäten für weitere Online- und Offlineanalysen haben.
Mit Azure API Management können Sie Ihre APIs mithilfe eines Schlüssels, eines Tokens und einer IP-Filterung sichern. Mit diesen Features können Sie flexible und differenzierte Kontingente und Geschwindigkeitsbeschränkungen erzwingen, das Shape und Verhalten Ihrer APIs mithilfe von Richtlinien ändern und die Leistung beim Zwischenspeichern von Antworten verbessern.
In diesem Handbuch und der Referenzbeispielanwendung (eShopOnContainers) ist die Architektur auf eine einfachere und benutzerdefinierte containerisierte Architektur beschränkt, um sich auf einfache Container zu konzentrieren, ohne PaaS-Produkte wie Azure API Management zu verwenden. Für große Microservice-basierte Anwendungen, die in Microsoft Azure bereitgestellt werden, empfehlen wir Ihnen jedoch, Azure API Management als Basis für Ihre API-Gateways in der Produktion zu bewerten.
Ozelot
Ocelot ist ein einfaches API-Gateway, das für einfachere Ansätze empfohlen wird. Ocelot ist ein Open Source .NET Core-basiertes API-Gateway, das speziell für Microservices-Architekturen erstellt wurde, die einheitliche Einstiegspunkte in ihre Systeme benötigen. Es ist leicht, schnell und skalierbar und bietet Routing und Authentifizierung unter vielen anderen Features.
Der Hauptgrund für die Auswahl von Ocelot für die eShopOnContainers-Referenzanwendung 2.0 besteht darin, dass Ocelot ein einfaches .NET Core-API-Gateway ist, das Sie in derselben Anwendungsbereitstellungsumgebung bereitstellen können, in der Sie Ihre Microservices/Container bereitstellen, z. B. einen Docker-Host, Kubernetes usw. Und da es auf .NET Core basiert, ist es plattformübergreifend, sodass Sie unter Linux oder Windows bereitstellen können.
Die vorherigen Diagramme mit benutzerdefinierten API-Gateways, die in Containern ausgeführt werden, sind genau, wie Sie Ocelot auch in einer Container- und Microservice-basierten Anwendung ausführen können.
Darüber hinaus gibt es viele andere Produkte auf dem Markt, die API-Gateways-Features wie Apigee, Kong, MuleSoft, WSO2 und andere Produkte wie Linkerd und Istio für Service Mesh-Eingangscontrollerfeatures anbieten.
Nach den ersten Abschnitten zur Architektur und Mustern erläutern die nächsten Abschnitte, wie API-Gateways mit Ocelot implementiert werden.
Nachteile des API-Gatewaymusters
Der wichtigste Nachteil ist, dass Sie beim Implementieren eines API-Gateways diese Ebene mit den internen Microservices koppeln. Eine Kopplung wie dies kann schwerwiegende Schwierigkeiten für Ihre Anwendung haben. Clemens Vaster, Architekt des Azure Service Bus-Teams, bezeichnet diese potenzielle Schwierigkeit in der Sitzung „Messaging and Microservices“ bei GOTO 2016 als „die neue ESB“.
Durch die Verwendung eines Microservices-API-Gateways wird ein zusätzlicher einzelner Fehlerpunkt erstellt.
Ein API-Gateway kann aufgrund des zusätzlichen Netzwerkaufrufs erhöhte Reaktionszeiten einführen. Dieser zusätzliche Aufruf hat jedoch in der Regel weniger Auswirkungen als eine Clientschnittstelle, die zu viel kommuniziert und direkt die internen Microservices aufruft.
Wenn die Skalierung nicht ordnungsgemäß erfolgt, kann das API-Gateway zu einem Engpass werden.
Ein API-Gateway erfordert zusätzliche Entwicklungskosten und zukünftige Wartung, wenn es benutzerdefinierte Logik und Datenaggregation enthält. Entwickler müssen das API-Gateway aktualisieren, um die Endpunkte jedes Microservice verfügbar zu machen. Darüber hinaus können Implementierungsänderungen in den internen Microservices Codeänderungen auf API-Gatewayebene verursachen. Wenn das API-Gateway jedoch nur Sicherheit, Protokollierung und Versionsverwaltung anwendet (wie bei Verwendung von Azure API Management), gelten diese zusätzlichen Entwicklungskosten möglicherweise nicht.
Wenn das API-Gateway von einem einzelnen Team entwickelt wird, kann es einen Entwicklungsengpässe geben. Dieser Aspekt ist ein weiterer Grund, warum ein besserer Ansatz darin besteht, mehrere feinkörnige API-Gateways zu haben, die auf unterschiedliche Clientanforderungen reagieren. Sie können das API-Gateway auch intern in mehrere Bereiche oder Ebenen unterteilen, die im Besitz der verschiedenen Teams sind, die an den internen Microservices arbeiten.
Weitere Ressourcen
Chris Richardson. Muster: API-Gateway /Back-End für Front-End
https://microservices.io/patterns/apigateway.htmlAPI-Gatewaymuster
https://learn.microsoft.com/azure/architecture/microservices/gatewayAggregations- und Kompositionsmuster
https://microservices.io/patterns/data/api-composition.htmlAzure-API-Verwaltung
https://azure.microsoft.com/services/api-management/Udi Dahan. Dienstorientierte Komposition
https://udidahan.com/2014/07/30/service-oriented-composition-with-video/Trennzeichen. Messaging und Microservices bei GOTO 2016 (Video)
https://www.youtube.com/watch?v=rXi5CLjIQ9kAPI Gateway im Überblick (ASP.NET Core API Gateway Tutorial Series)
https://www.pogsdotnet.com/2018/08/api-gateway-in-nutshell.html