GraphQL- und Microservice-Architektur

175

Ich versuche zu verstehen, wo GraphQL am besten für die Verwendung in einer Microservice-Architektur geeignet ist.

Es gibt einige Debatten darüber, dass nur ein GraphQL-Schema als API-Gateway fungiert, das die Anforderung an die Ziel-Microservices weiterleitet und deren Antwort erzwingt. Microservices würden weiterhin das REST / Thrift-Protokoll für Kommunikationsgedanken verwenden.

Ein anderer Ansatz besteht darin, mehrere GraphQL-Schemas pro Mikroservice zu verwenden. Ein kleinerer API-Gateway-Server, der die Anforderung mit allen Informationen der Anforderung + der GraphQL-Abfrage an den Ziel-Microservice weiterleitet.

1. Ansatz

Wenn Sie 1 GraphQL-Schema als API-Gateway haben, hat dies einen Nachteil: Jedes Mal, wenn Sie die Eingabe / Ausgabe Ihres Microservice-Vertrags ändern, müssen wir das GraphQL-Schema auf der API-Gateway-Seite entsprechend ändern.

2. Ansatz

Wenn Sie mehrere GraphQL-Schemas pro Microservices verwenden, ist dies in gewisser Weise sinnvoll, da GraphQL eine Schemadefinition erzwingt und der Verbraucher die vom Microservice angegebenen Ein- / Ausgaben berücksichtigen muss.

Fragen

  • Ob GraphQL für das Entwerfen einer Microservice-Architektur geeignet ist?

  • Wie würden Sie ein API-Gateway mit einer möglichen GraphQL-Implementierung entwerfen?

Fabrizio Fenoglio
quelle

Antworten:

240

Nähern Sie sich auf jeden Fall # 1.

Wenn Ihre Clients mit mehreren GraphQL-Diensten sprechen (wie in Ansatz 2), wird der Zweck der Verwendung von GraphQL in erster Linie völlig zunichte gemacht, nämlich ein Schema über Ihre gesamten Anwendungsdaten bereitzustellen , damit diese in einem einzigen Roundtrip abgerufen werden können.

Eine gemeinsame Nichts- Architektur mag aus Sicht der Microservices vernünftig erscheinen, aber für Ihren clientseitigen Code ist dies ein absoluter Albtraum, da Sie jedes Mal, wenn Sie einen Ihrer Microservices ändern, alle Ihre Clients aktualisieren müssen . Sie werden es auf jeden Fall bereuen.

GraphQL und Microservices passen perfekt zusammen, da GraphQL die Tatsache verbirgt, dass Sie eine Microservice-Architektur vor den Clients haben. Aus Backend-Sicht möchten Sie alles in Microservices aufteilen. Aus Frontend-Sicht möchten Sie jedoch, dass alle Ihre Daten von einer einzigen API stammen. Die Verwendung von GraphQL ist der beste Weg, den ich kenne, damit Sie beides tun können. Sie können Ihr Backend in Microservices aufteilen und gleichzeitig eine einzige API für Ihre gesamte Anwendung bereitstellen sowie Verknüpfungen zwischen Daten von verschiedenen Diensten zulassen.

Wenn Sie REST nicht für Ihre Microservices verwenden möchten, können Sie natürlich jede über eine eigene GraphQL-API verfügen, aber Sie sollten dennoch über ein API-Gateway verfügen. Der Grund, warum Benutzer API-Gateways verwenden, besteht darin, das Aufrufen von Microservices aus Clientanwendungen einfacher zu gestalten, nicht weil es gut in das Microservices-Muster passt.

Helfer
quelle
2
@helfer: Das macht wirklich Sinn :) danke. Ich habe einige Fragen zu dieser wunderschönen Antwort. - Sie sagen, dass GraphQL als API-Gateway verwendet werden muss? - Angenommen , ich habe einen Order Microservice, der entweder einen REST- oder einen GraphQL-Endpunkt verfügbar macht. Sobald ich damit fertig bin, muss ich das Haupt-GraphQL-Schema aktualisieren, um genau die Daten wiederzugeben, die der Microservice verfügbar macht. Klingt es nicht nach Vervielfältigung oder Abkehr von der Microservice-Kultur, die unabhängig eingesetzt werden sollte? Müssen Änderungen an einem Microservice im Haupt-GraphQL-Schema berücksichtigt / dupliziert werden?
Fabrizio Fenoglio
13
@Fabrizio Das Schöne an GraphQL ist, dass das GraphQL-Schema auch dann unverändert bleiben kann, wenn sich die Backend-REST-API ändert, solange es eine Möglichkeit gibt, die Daten abzurufen, die der REST-Service zuvor verfügbar gemacht hat. Wenn mehr Daten verfügbar gemacht werden, besteht die kanonische Methode darin, einfach neue Felder / Typen zum vorhandenen Schema hinzuzufügen. Die Leute bei Facebook, die GraphQL erstellt haben, sagten mir, dass sie in vier Jahren nie eine grundlegende Änderung an ihrem Schema vorgenommen haben. Alle vorgenommenen Änderungen waren additiv, was bedeutet, dass neue Clients die neue Funktionalität nutzen können, während alte Clients weiterhin funktionieren.
Helfer
4
Richtig! :) Danke, dass du das geschrieben hast! Ich folge dir auf Medium und auf Github durch Apollo Repos! Ihre Artikel und Beiträge sind sehr wertvoll! :) Mach weiter so! Ich denke auch, dass ein mittlerer Artikel mit dem Thema GraphQL + Microservices sehr angenehm zu lesen sein wird!
Fabrizio Fenoglio
1
Danke, das werde ich mir merken. Ich habe definitiv vor, irgendwann über GraphQL und Microservices zu schreiben, aber wahrscheinlich nicht in den nächsten Wochen.
Helfer
Wie wäre es mit der Kombination von Option 2 und github.com/AEB-labs/graphql-weaver ?
Mohsen
35

Siehe den Artikel hier , die sagt , wie und warum Ansatz # 1 funktioniert besser. Schauen Sie sich auch das folgende Bild aus dem Artikel an, den ich erwähnt habe: Geben Sie hier die Bildbeschreibung ein

Einer der Hauptvorteile von allem, was sich hinter einem einzelnen Endpunkt befindet, besteht darin, dass Daten effektiver weitergeleitet werden können, als wenn jede Anforderung ihren eigenen Dienst hätte. Während dies der häufig angepriesene Wert von GraphQL ist, eine Verringerung der Komplexität und des Service-Creep, ermöglicht die resultierende Datenstruktur auch, dass der Datenbesitz äußerst genau definiert und klar abgegrenzt wird.

Ein weiterer Vorteil der Einführung von GraphQL ist die Tatsache, dass Sie grundsätzlich eine bessere Kontrolle über den Datenladevorgang erlangen können. Da der Prozess für Datenlader an einem eigenen Endpunkt ausgeführt wird, können Sie die Anforderung entweder teilweise, vollständig oder mit Einschränkungen berücksichtigen und so die Datenübertragung äußerst detailliert steuern.

Der folgende Artikel erklärt diese beiden Vorteile zusammen mit anderen sehr gut: https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/

Enayat
quelle
HI, entschuldigen Sie die Noob-Fragen, aber ist Ihr graphQL-Gateway nicht ein neuer Aufbewahrungspunkt? Wenn ich beispielsweise einen Warenkorbdienst habe, der plötzlich überfordert ist, würde mein graphQL-Gateway dann nicht auch kaputt gehen? Grundsätzlich bin ich mir seiner Rolle nicht sicher, soll dieses Gateway viele Resolver für jeden Dienst enthalten?
Eric Burel
1
@ EricBurel Danke für die Frage. Soweit ich aus dem Artikel verstanden habe, sind alle Schemata verschiedener Dienste unter einem GraphQL-Schema zusammengefasst. Wie Sie bereits erwähnt haben, befinden sich andere Dienste immer noch in ihren eigenen Datensätzen. In Bezug auf die Möglichkeit einer einzigen Fehlerquelle für das graphQL-Gateway gibt es immer andere Optionen, z. B. die Bereitstellung eines Sicherungsplans. Bitte lesen Sie diesen Artikel ( labs.getninjas.com.br/… ) für weitere Informationen. Hoffe das hilft.
Enayat
Wie testen Sie das zentrale API-Gateway und die einzelnen Dienste? Führen Sie eine Integration durch oder verspotten Sie die http-Antwort?
Jaime Sangcap
7

Für Ansatz 2 wähle ich diese Vorgehensweise, da dies viel einfacher ist, als das lästige API-Gateway manuell zu warten. Auf diese Weise können Sie Ihre Dienste unabhängig entwickeln. Machen Sie das Leben viel einfacher: P.

Es gibt einige großartige Werkzeuge, um Schemata zu einem zu kombinieren, z. B. Graphql-Weaver und Apollo Graphql-Werkzeuge . Ich verwende sie graphql-weaver, sie sind einfach zu verwenden und funktionieren hervorragend.

HFX
quelle
Die Verwendung von GraphQL in Android ist unbedingt erforderlich, damit ich eine .graphql-Datei mit allen Abfragen erstelle. Oder kann ich sie einfach ohne diese Datei im Code erstellen?
MauroAlexandro
1
@ MauroAlexandro Ich bin kein Android-Typ, aber Sie können die Abfragen in verschiedenen Dateien haben. Es ist eher ein Designproblem. IMHO, ich bevorzuge den ersten :)
HFX
5

Ab Mitte 2019 hat die Lösung für den 1. Ansatz jetzt den Namen " Schema Federation ", der von den Apollo-Leuten geprägt wurde (früher wurde dies oft als GraphQL-Stitching bezeichnet). Sie schlagen auch die Module vor @apollo/federationund @apollo/gatewaydafür.

HINZUFÜGEN: Bitte beachten Sie, dass Sie mit Schema Federation das Schema auf Gateway-Ebene nicht ändern können. Für jedes Bit, das Sie in Ihrem Schema benötigen, benötigen Sie einen separaten Dienst.

Vanthome
quelle
Es ist auch gültig zu wissen, dass diese Lösung Apollo Server erfordert, der in der kostenlosen Version leicht eingeschränkt ist (maximal 25 Millionen Anfragen pro Monat)
Marx
0

Ab 2019 ist es am besten, Microservises zu schreiben, die die Apollo-Gateway- Spezifikation implementieren, und diese Dienste dann mithilfe eines Gateways nach Ansatz 1 zusammenzukleben. Der schnellste Weg, um das Gateway zu erstellen, ist ein Docker-Image wie dieses. Verwenden Sie dann Docker-Compose, um alle Dienste gleichzeitig zu starten:

version: '3'

services:
    service1:
        build: service1
    service2:
        build: service2
    gateway:
        ports:
            - 80:80
        image: xmorse/apollo-federation-gateway
        environment: 
            - CACHE_MAX_AGE=5
            - "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
            - URL_0=http://service1
            - URL_1=http://service2
Morse
quelle
0

Ich glaube, dass die Verwendung eines benutzerdefinierten API-Gateways als Orchestrierungsdienst für komplexe unternehmensorientierte Anwendungen sehr sinnvoll sein kann. GraphQL kann eine gute Technologie für diesen Orchestrierungsdienst sein, zumindest was die Abfrage betrifft. Der Vorteil Ihres ersten Ansatzes (ein Schema für alle Mikrodienste) besteht in der Möglichkeit, die Daten mehrerer Mikrodienste in einer einzigen Anforderung zusammenzufügen. Das kann je nach Ihrer Situation sehr wichtig sein oder auch nicht. Wenn die GUI das gleichzeitige Rendern von Daten von mehreren Microservices erfordert, kann dieser Ansatz den Clientcode vereinfachen, sodass ein einzelner Aufruf Daten zurückgeben kann, die für die Datenbindung mit den GUI-Elementen von Frameworks wie Angular oder React geeignet sind. Dieser Vorteil gilt nicht für Mutationen.

Der Nachteil ist die enge Kopplung zwischen den Daten-APIs und dem Orchestrierungsdienst. Releases können nicht mehr atomar sein. Wenn Sie keine rückwärtsbrechenden Änderungen in Ihren Daten-APIs einführen, kann dies nur beim Zurücksetzen einer Version zu Komplexität führen. Wenn Sie beispielsweise neue Versionen von zwei Daten-APIs mit den entsprechenden Änderungen im Orchestrierungsdienst veröffentlichen möchten und eine dieser Versionen zurücksetzen müssen, die andere jedoch nicht, müssen Sie ohnehin alle drei zurücksetzen.

In diesem Vergleich von GraphQL mit REST werden Sie feststellen, dass GraphQL nicht ganz so effizient ist wie RESTful-APIs. Daher würde ich nicht empfehlen, REST für die Daten-APIs durch GraphQL zu ersetzen.

Glenn
quelle
0

Bei Frage 1 erkannte Intuit vor einigen Jahren die Leistungsfähigkeit von GraphQL an, als die Umstellung auf das One Intuit API-Ökosystem angekündigt wurde ( https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations) -quickbooks-connect-2017 ). Intuit entschied sich für Ansatz 1. Der von Ihnen erwähnte Nachteil hindert Entwickler tatsächlich daran, wichtige Schemaänderungen einzuführen, die möglicherweise Clientanwendungen stören könnten.

GraphQL hat auf verschiedene Weise dazu beigetragen, die Produktivität von Entwicklern zu verbessern.

  1. Beim Entwerfen eines neuen Mikrodienstes für eine Domäne vereinbaren die Ingenieure (Backend / Frontend / Stakeholder) ein Schema für die Domänenentitäten. Sobald das Schema genehmigt wurde, wird es mit dem Masterdomänenschema (universell) zusammengeführt und auf dem Gateway bereitgestellt. Front-End-Ingenieure können mit der Codierung von Clientanwendungen mit diesem Schema beginnen, während Back-End-Ingenieure die Funktionalität implementieren. Ein einziges universelles Schema bedeutet, dass es keine zwei Mikrodienste mit redundanter Funktionalität gibt.
  2. GraphQL hat dazu beigetragen, dass Clientanwendungen einfacher und schneller werden. Möchten Sie Daten von mehreren Microservices abrufen / aktualisieren? Alles, was Clientanwendungen tun müssen, ist, EINE GraphQL-Anforderung auszulösen, und die API-Gateway-Abstraktionsschicht sorgt dafür, dass Daten aus mehreren Quellen (Microservices) abgerufen und zusammengestellt werden. Open-Source-Frameworks wie Apollo ( https://www.apollographql.com/ ) haben die Einführung von GraphQL beschleunigt.

  3. Da Mobilgeräte die erste Wahl für moderne Anwendungen sind, ist es wichtig, für geringere Datenbandbreitenanforderungen ab Ground Zero zu entwerfen. GraphQL hilft, indem Client-Apps nur bestimmte Felder anfordern können.

Zu Frage 2: Wir haben am API-Gateway eine benutzerdefinierte Abstraktionsschicht erstellt, die weiß, welcher Teil des Schemas welchem ​​Dienst (Anbieter) gehört. Wenn eine Abfrageanforderung eintrifft, leitet die Abstraktionsschicht die Anforderung an die entsprechenden Dienste weiter. Sobald der zugrunde liegende Dienst die Antwort zurückgibt, ist die Abstraktionsschicht dafür verantwortlich, die angeforderten Felder zurückzugeben.

Heutzutage gibt es jedoch mehrere Plattformen (Apollo-Server, Graphql-Yoga usw.), mit denen man in kürzester Zeit eine GraphQL-Abstraktionsschicht erstellen kann.

Nacharya
quelle
0

Ich habe mit GraphQL und Microservices gearbeitet

Aufgrund meiner Erfahrung funktioniert für mich eine Kombination beider Ansätze, abhängig von der Funktionalität / Verwendung. Ich werde niemals ein einziges Gateway wie in Ansatz 1 haben ... aber keine Grafik für jeden Mikrodienst als Ansatz 2.

Basierend auf dem Bild der Antwort von Enayat würde ich in diesem Fall beispielsweise 3 Grafik-Gateways haben (nicht 5 wie im Bild).

Geben Sie hier die Bildbeschreibung ein

  • App (Produkt, Warenkorb, Versand, Inventar, benötigt / mit anderen Dienstleistungen verbunden)

  • Zahlung

  • Benutzer

Auf diese Weise müssen Sie dem Design der benötigten / verknüpften Minimaldaten, die von den abhängigen Diensten verfügbar gemacht werden, wie Authentifizierungstoken, Benutzer-ID, Zahlungs-ID und Zahlungsstatus, besondere Aufmerksamkeit widmen

Nach meiner Erfahrung habe ich zum Beispiel das "Benutzer" -Gateway, in GraphQL habe ich die Benutzerabfragen / -mutationen, Anmelden, Anmelden, Abmelden, Passwort ändern, E-Mail wiederherstellen, E-Mail bestätigen, Konto löschen, Profil bearbeiten, Bild hochladen , etc ... dieses Diagramm alleine ist ziemlich groß!, es ist getrennt, weil sich die anderen Dienste / Gateways am Ende nur um die resultierenden Informationen wie Benutzer-ID, Name oder Token kümmern.

Dieser Weg ist einfacher zu ...

  • Skalieren / Herunterfahren der verschiedenen Gateway-Knoten je nach Verwendung. (Zum Beispiel bearbeiten Leute möglicherweise nicht immer ihr Profil oder zahlen ... aber die Suche nach Produkten wird möglicherweise häufiger verwendet).

  • Sobald ein Gateway ausgereift ist, wächst, die Verwendung bekannt ist oder Sie über mehr Fachwissen in der Domäne verfügen, können Sie feststellen, welcher Teil des Schemas möglicherweise ein eigenes Gateway hat (... ist mir mit einem riesigen Schema passiert, das mit Git-Repositorys interagiert Ich habe das Gateway, das mit einem Repository interagiert, getrennt und festgestellt, dass die einzige Eingabe / verknüpfte Information ... der Ordnerpfad und der erwartete Zweig war.

  • Die Historie Ihrer Repositorys ist klarer und Sie können ein Repository / Entwickler / Team haben, das einem Gateway und den damit verbundenen Microservices gewidmet ist.

AKTUALISIEREN:

Ich habe einen Kubernetes-Cluster online, der denselben Ansatz verwendet, den ich hier mit allen Backends unter Verwendung von GraphQL, alles OpenSource, beschreibe. Hier ist das Haupt-Repository: https://github.com/vicjicaman/microservice-realm

Dies ist eine Aktualisierung meiner Antwort, da ich denke, dass es besser ist, wenn die Antwort / der Ansatz aus einem gesicherten Code besteht, der ausgeführt wird und konsultiert / überprüft werden kann. Ich hoffe, dass dies hilft.

Victor Jimenez
quelle
-3

Da die Microservice-Architektur keine ordnungsgemäße Definition hat, gibt es kein spezifisches Modell für diesen Stil, die meisten weisen jedoch nur wenige bemerkenswerte Merkmale auf. Bei der Microservices-Architektur kann jeder Service in einzelne kleine Komponenten unterteilt werden individuell optimiert und bereitgestellt, ohne die Anwendungsintegrität zu beeinträchtigen. Dies bedeutet, dass Sie einfach einige Dienste ändern können, ohne die Anwendung durch benutzerdefinierte Entwicklung von Microservices- Apps erneut bereitstellen zu müssen .

Demetrius Franco
quelle
Auch wenn es keine "richtige Definition" gibt, handelt es sich um ein gut verstandenes Konzept, das im Kontext der Frage klar abgegrenzt ist. Abgesehen davon geht Ihre Antwort überhaupt nicht auf die Frage ein.
Roy Prins
-7

Mehr über Microservices, ich denke, GraphQL könnte auch in der Architektur ohne Server perfekt funktionieren. Ich benutze kein GraphQL, aber ich habe mein eigenes ähnliches Projekt . Ich benutze es als Aggregator, der viele Funktionen aufruft und zu einem einzigen Ergebnis konzentriert. Ich denke, Sie könnten das gleiche Muster für GraphQL anwenden.

Giap Nguyen
quelle
2
Entschuldigung, aber dies ist für die Frage des OP überhaupt nicht relevant. Die Frage betrifft zwei spezifische Ansätze mit GraphQL. Dies hätte besser als Kommentar eingefügt werden können.
Tiomno