Zurück
Tech 6 Min. Lesezeit - 21 Febr. 20 - Bastien Landry

Kurze Einführung in GraphQL

Was ist GraphQL? Oder besser gesagt, beginnen wir mit der Frage, was GraphQL nicht ist? Trotz seines Namens ist GraphQL keine Alternative zu MySQL als Datenbank und auch keine Konkurrenzsprache zu SQL. Tatsächlich ist GraphQL eine Abfragesprache für APIs. Wenn wir einen kurzen Überblick über die verschiedenen Methoden zum Senden und Empfangen von Daten im Laufe der Zeit geben, können wir drei Phasen unterscheiden: das Steinzeitalter, das Bronzezeitalter und das Eisenzeitalter.
In unserer kleinen Analogie entspricht das Steinzeitalter dem SOAP-Protokoll. Konkret senden SOAP-APIs Daten im XML-Format, in der Regel unter Verwendung des HTTP-Protokolls (aber nicht zwingend). Das eigentliche Problem bei SOAP ist der ausführliche Aspekt der Anfragen; das Format ist schwerfällig und für die heutigen Herausforderungen ungeeignet. Es musste eine Lösung gefunden werden, indem man zum Bronzezeitalter, der REST-API, überging. Dabei ist REST kein Protokoll (im Gegensatz zu SOAP), sondern eher eine Reihe von Regeln und Einschränkungen, die verwendet werden, um ein Minimum an Konsistenz und Interoperabilität im Internet herzustellen. REST verwendet ausschliesslich das HTTP-Protokoll und kommuniziert in der Regel über ein JSON-Format. Wie Monsieur Jourdain im Bürger als Edelmann, der Prosa sprach, ohne es zu wissen, haben viele schliesslich REST verwendet, ohne es zu wissen, indem sie zum Beispiel einen einfachen Node.js-Server eingerichtet haben. Der Hauptnachteil von REST ist auch sein Hauptvorteil, seine Formbarkeit. Es gibt keinen wirklich von allen befolgten Standard und das kann schnell zu einem «Wilden Westen» werden! Wir mussten also zum Eisenzeitalter übergehen. Das Eisenzeitalter, das ist GraphQL.
Wir werden uns nicht zu lange mit der Theorie aufhalten, aber es ist wichtig zu verstehen, dass GraphQL im Gegensatz zu den anderen eine Sprache ist; es ist eine einfache und elegante Art, Anfragen an den Server zu stellen. GraphQL verwendet die POST-Methode des HTTP-Protokolls und im Gegensatz zu REST verwendet es nur eine einzige Route. GraphQL benötigt nur einen Endpoint. Um dies besser zu verstehen, werden wir einerseits eine kleine Website mit REST erstellen und uns ansehen, wie wir diese mit GraphQL anpassen könnten.
Unsere Website wird sich mit dem geheimnisvollen Volk der Galadhrim befassen, einem Elfenvolk aus dem Herrn der Ringe. Dieses Volk lebt im Wald und baut Baumhäuser als Wohnstätten. In unserer Welt kann jeder Elf auch Freunde und ein Haus haben. Wenn wir aus diesen Informationen eine Datenbank aufbauen wollen, bräuchten wir:
  • Elfen : elfeId (Int), name (String), age (Int), houseId (Int)
  • Häuser : houseId (Int), surface (float), woodType (enum)
  • Freunde : friendId (Int), firstElfeId (Int), secondElfeId (Int)
Zusätzlich dazu werden wir einen sehr einfachen Express-Server einrichten (siehe https://expressjs.com/fr/starter/hello-world.html falls nötig). Ziel ist es, dem Front-End die Informationen eines Elfen auf einer Seite zurückzugeben: seinen Namen, sein Alter, die Merkmale seines Hauses, aber auch alle seine Freunde. Für das Front-End werden wir create-react-app verwenden (https://github.com/facebook/create-react-app).
So sollte unsere Seite aussehen:
GraphQL (1)
Wir können 4 Teile unterscheiden:
  • Meine persönlichen Informationen
  • Die Fläche unseres Hauses und die verwendete Holzart
  • Die Liste meiner Freunde
  • Die Liste der Freunde meiner Freunde
Mit REST
Technisch gesehen müssten wir unter Verwendung einer REST-API die folgenden Aufrufe machen:
  • GET /elfe pour récupérer les données de mon elfe
  • GET /house pour récupérer les données de ma maison
  • GET /friends pour récupérer l’ensemble de mes amis
  • GET /friends?elfeIds=[1,4,8] pour récupérer les amis de mes amis
Wir könnten technisch alle diese Anfragen auf einmal machen, aber das wäre spezifisch für diese Seite und unsere gesamte API würde zu Einzelfällen werden. Das ist keine wirklich gute Praxis, da es die Lesbarkeit des Codes und das Verständnis der API für einen Entwickler, der mit einer Vielzahl spezifischer Endpoints zu tun hätte, erheblich erschwert. Auch um die schlankeste und einfachste Architektur zu erhalten, ist es wohl logischer, 4 aufeinanderfolgende API-Aufrufe zu tätigen.
Mit GraphQL
Mit GraphQL gibt es nur einen Aufruf:
  • POST /graphql
Tatsächlich ist GraphQL eine Sprache, und die ganze Feinheit liegt im Inhalt (body), der in der Anfrage gesendet wird. Dieser Inhalt folgt einem bestimmten Format und wird von unserem Back-End interpretiert. So sieht unser body aus:
carbon (8)
Versuchen wir, den Inhalt zu sezieren:
  • Das Wort query bezieht sich auf den Typ der Anfrage, die man an GraphQL stellt; wir unterscheiden zwei Typen: query und die Typen mutation. Eine query fordert Daten vom Server an, eine mutation nimmt eine Änderung vor, zum Beispiel eine Datenbankeinfügung. Hier fragen wir Informationen ab, daher stellen wir eine query-Anfrage. Es gibt auch einen anderen Typ, der subscription genannt wird, aber wir verwenden ihn hier nicht.
  • Das Wort initialization ist nicht sehr wichtig, es ist der Name, den ich meiner query gegeben habe; Sie hätten alles Mögliche eingeben können, zum Beispiel legolas, und es hätte funktioniert!
Das Wort elfe hingegen ist wichtig; es bezieht sich auf die query die ich verwenden werde. Ich erkläre es Ihnen: Wenn ich meine GraphQL-API erstelle, muss ich ihr eine Darstellung meiner Datenbank schreiben, damit sie die Attribute jedes Einzelnen, die Verknüpfungen usw. verstehen kann. Meine query wird so aussehen:
carbon (6)
Wir werden ihn also bitten, mir einen Elfen für eine als Parameter übergebene elfeId zurückzugeben (in unserem Fall ist elfeId 1). Wir verwenden dann einen resolver, der meine Informationen abruft. Vereinfacht gesagt ist ein resolver eine Funktion, die Daten aus der Datenbank über eine SQL-Anfrage abruft, zum Beispiel. 
  • Der Typ Elfe den wir in unserer query definieren, besitzt also alle Attribute, die wir brauchen: einen Namen, ein Alter, ein Haus und Freunde. Der resolver getElfeForId wird also selbst andere Funktionen verwenden, um das zu finden, was wir in der Datenbank benötigen. 
Der Typ Elfe, von dem wir sprechen, ist im Back-End wie folgt definiert:
carbon (12)
Es ist wichtig zu verstehen, dass es hier keine Magie gibt; man muss explizit SQL-Abfragen machen, um dann das Elfe-Objekt zu erzeugen, das wir erwarten. Somit sind die Funktionen getHouseForElfeId und getFriendsForElfeId letztendlich SQL-Abfragen. In GraphQL haben die Felder (fields) Typen; diese Typen können primitiv sein, wie Ganzzahlen (GraphQLInt), oder generierte Typen, wie der Typ Elfe. So kann man ein Objekt oder eine Liste von Objekten (unter Verwendung von GraphQLList) als Feld zurückgeben. Auch mit der oben vorgenommenen Definition des Elfe-Objekts erwartet das Feld friends, eine Liste von Elfen zurückzugeben!
Es gibt also viel Vorarbeit zu leisten, aber sobald diese erledigt ist, muss man das Back-End nicht mehr anfassen, keine neuen Routen mehr erstellen usw.! Alles läuft dann über das Front-End, das unsere API nach dem fragen kann, was es benötigt. Wenn wir auf einer Seite beispielsweise nur den Namen des Elfen benötigen, wird unsere Anfrage so aussehen:
carbon (9)
Keine Arbeit muss im Back-End erledigt werden, alles ist bereits fertig. Wir können also eine Einkaufsliste für alles erstellen, was wir zum richtigen Zeitpunkt benötigen!
Das ist die Essenz von GraphQL in wenigen Zeilen. Es ist wichtig zu betonen, dass GraphQL einen nicht zu unterschätzenden Standard und eine Benutzerfreundlichkeit mit sich bringt. Neben dem praktischen Aspekt vereinfacht das Fehlermanagement von GraphQL dessen Implementierung; wenn etwas nicht stimmt, wird GraphQL uns das schnell mitteilen! Einige werden sich vielleicht fragen, wie Lese- und Bearbeitungsrechte verwaltet werden können; dafür muss man den Begriff des context ! Viele Aspekte von GraphQL können vertieft werden (und werden es vielleicht in einem zukünftigen Artikel?), aber die Idee dieses Artikels ist es, den Bedarf und die von GraphQL angebotene Lösung zu präsentieren.

Möchten Sie bei der Lancierung Ihres digitalen Projekts begleitet werden?

Reichen Sie Ihr Projekt jetzt ein