GraphQL: ein wichtiger Schritt für Headless Magento 2

Was ist GraphQL?

GraphQL ist ein API-Standard, ähnlich wie REST oder SOAP. Die GraphQL-Spezifikation definiert eine Abfragesprache („query language“) und ein Typen-System („type system“). Man kann damit Lese- und Schreib-Abfragen in Programmiersprachen-neutraler Weise schreiben. In vielen Anwendungsfällen ist es ein potentieller Nachfolger für REST oder selbstgebaute nicht-standardisierte Webservice-Architekturen. Aufgrund seiner Vorteile ist es besonders für den Einsatz in Web-Applikationen, zum Beispiel Online-Shops attraktiv.

Facebook entwickelte GraphQL ursprünglich 2012 intern für die Verbesserung der mobilen Anwendungen. 2015 wurde es als Open Source veröffentlicht. Seitdem erfreut sich die Technologie stark steigender Beliebtheit. Zu den Unternehmen, die GraphQL verwenden (Stand: Jänner 2021) zählen unter anderem Facebook, GitHub, Shopify, Twitter, Yelp, WordPress und The New York Times.

Um das Commitment zu GraphQL zu festigen (und vielleicht auch, um die Abhängigkeit von Facebook zu verringern, haben Branchen-Größen hinter GraphQL wie Audi, CNBC, GitHub, Netflix, Shopify, The New York Times, Twitter, Pinterest und Help eine Foundation gegründet, um GraphQL ein offenes und neutrales Zuhause zu bieten und die Verbreitung von GraphQL zu fördern.

Warum ist GraphQL beliebt?

GraphQL erlebt spätestens seit 2018 einen Hype in der EntwicklerInnen-Szene. Die Vorteile bedeuten nicht nur mehr Komfort für die Developer. Auch Unternehmen profitieren, weil sich Web-Anwendungen damit schneller entwickeln lassen und günstiger im Betrieb sind.

Vorteile

Die folgende Liste enthält vor allem technische Details. Sie wirken sich direkt auf betriebliche und wirtschaftliche Vorteile aus.

Datensparsamkeit

Bei REST kann man sich nicht aussuchen, welche Datenfelder man zurück bekommt. Zum Beispiel erhalte ich bei einem REST-Call ein Produkt mit all seinen Attributen, obwohl ich eigentlich nur den Produkt-Namen und die SKU benötige. Das bezeichnet man als „overfetching“. Manchmal erhält man mit dem einen Call auch zu wenige Daten („underfetching“) und muss weitere Anfragen stellen.

Mit GraphQL hingegen definiere ich genau, welche Datenfelder ich haben möchte. Das reduziert die übertragene Datenmenge. Es fällt weniger Traffic an und die Daten werden schneller übertragen.

Weniger Requests

Mit REST muss man oft viele Anfragen stellen. Zum Beispiel holt man sich zuerst anhand bestimmter Kriterien eine Liste von Bestellungen und erhält die Bestell-Nummern. Dann muss man für jede Bestellung einen extra Abruf starten. Wenn ich auf derselben Seite Produkt- oder Kategorie-Informationen benötige, sind das viele weitere Anfragen. Diese Netzwerk-Anfragen werden noch dazu wie im Wasserfall-Prinzip hintereinander abgearbeitet. Sie finden also nicht parallel statt.

GraphQL erlaubt es, alle Entitäten (Bestellungen, Produkte, Kategorien, …) mit einem einzigen Call abzurufen. Man kann auch Hierarchien von Daten mit einem einzelnen Call abfragen. Dadurch reduziert sich die Zahl der „Round-Trips“ gewaltig. Das verspricht wiederum eine bessere Geschwindigkeit und weniger benötigte Bandbreite.

Davon profitiert man in Magento 2 noch mehr, weil man sich die Zeit für das „Bootstraping“ von Magento 2 spart. Damit gemeint ist, dass bei jedem Seiten- oder Schnittstellenaufruf bestimmter Code ausgeführt wird um die Verarbeitung starten zu können. Das passiert bei dem GraphQL-Call nur einmal, weil man alle Entitäten auf einmal abfragt.

Automatische Dokumentation der Schnittstelle

Dokumentation in GraphQL ist ein „first-class citizen“. Das heißt: wenn man das Schema für die Lese- und Schreib-Anfragen definiert, kann und sollte man jedes Feld und jede Entität gleich mit dokumentieren. Daraus kann man dann mit Tools einfach und automatisch eine API-Dokumentation generieren. Dank der Dokumentation binden EntwicklerInnen die Schnittstelle schneller und günstiger ein.

Weil die Dokumentation direkt an der gleichen Stelle wie die Schema-Definition erfolgt kann man leicht die Dokumentation aktuell halten. Das Risiko sinkt stark, dass die Dokumentation und Implementierung auseinander laufen.

Zusätzlich kann man über das Inspection-System das Schema erkunden, wovon auch die Entwickler-Umgebungen (IDEs) profitieren, die somit Auto-Completion und co. anbieten können.

Typisierung

Ein wichtiges Feature für die Stabilität der Schnittstelle ist die starke Typisierung. Das heißt: für jedes Feld wird der Datentyp (Text, Zahl, …) explizit festgelegt. Außerdem wird definiert, ob ein Feld leer sein darf und ob genau ein oder mehrere Werte erwartet werden.

Das verhindert schwammige Definitionen und hilft oft, subtile Fehler in der Implementierung zu vermeiden.

Validierung

Dank des Schema können die Anfragen validiert, das heißt auf ihre Gültigkeit überprüft werden.

Keine Versionierung nötig

Gemeint ist damit natürlich nicht die Versionierung von Code: die muss immer erfolgen. Man muss aber nicht mehr wie in REST eine Version 1, 2, 2.1, … definieren, was unübersichtlich werden und zu Fehlern führen kann. Der Grund: „Deprecation“ ist ein in GraphQL eingebautes Konzept. Ich kann also kennzeichnen, wenn ein Feld nicht mehr verwenden soll. Auch die Deprecation ist  dokumentierbar. So hält man fest, warum das Feld nicht mehr verwendet werden soll und was die Alternative ist. Da die UserInnen selbst entscheiden welche Felder abgefragt werden, kann man leicht im Hintergrund neue Felder anbieten ohne verschiedene Versionen der Schnittstelle veröffentlichen zu müssen.

Man ist nicht komplett vor „Breaking Changes“ gefeit und muss sich trotzdem von Beginn an gründliche Gedanken über die Schnittstellen-Definition machen. Insgesamt kommen inkompatible Änderungen wesentlich seltener vor als bei Änderungen an REST-Schnittstellen.

Eine zentrale API für viele Services im Hintergrund

Für große, komplexe Systeme gibt es einen weiteren Vorteil: das in der Spezifikation fix vorgesehene „GraphQL schema stitching„. Dieses erlaubt es, zu externen Systemen hin eine zentrale API anzubinden, im Hintergrund aber beliebig viele Services zu implementieren.

So wird es möglich, für verschiedene Domänen getrennte GraphQL-Services zu implementieren – zum Beispiel einen Microservice für Preisabfragen und einen für Verfügbarkeitsabfragen. Nach außen hin, zum Beispiel für externe Systeme oder Dritt-Anbieter, verbindet man die Services über Schema-Stitching und macht die gewünschten Teile der Microservices über eine gemeinsame API zugänglich.

Nachteile

Wie alles im Leben gibt es auch Nachteile beim Einsatz dieser Technologie. Diese können großteils durch Middleware wie Apollo abgefangen werden. Für die Teile, bei denen Apollo nicht aushelfen kann ist Magento 2 dafür verantwortlich, sie zu verbessern.

  • Das Auslesen der Daten auf der Server-Seite muss effizient implementiert werden, um gute Performance zu gewährleisten. Darüber hinaus muss man darauf achten, Fallstricke wie Rekursionen zu vermeiden.
  • Bei öffentlich erreichbaren APIs muss Rate-Limiting mitbedacht werden, um zu verhindern dass jemand der Server mit einer großen Anzahl an (komplexen) Fragen in die Knie zwingt. Rate-Limiting ist gerade bei hierarchischen Daten-Strukturen unter Umständen nicht einfach gut umzusetzen.
  • Dasselbe gilt für das zugegebenermaßen nie ganz triviale Thema Caching und Cache-Invalidierung. Zum Glück können Libraries wie jene der Apollo-Plattform hier Abhilfe schaffen.

Wann ist REST besser geeignet?

  1. Wenn Sie über eine umfangreiche Legacy-Anwendung verfügen, die bereits REST unterstützt und für die eine neue Umsetzung der Schnittstelle nicht wirtschaftlich ist.
  2. Wenn Ihre Applikation bzw. Domäne stark in klassischen Ressourcen denkt.
  3. Wenn Sie die Flexibilität von GraphQL nicht benötigen.

GraphQL in Magento 2

Mit Version 2.3.0 hielt die erste Ausbaustufe von GraphQL Einzug in Magento 2. Seitdem gibt es in jedem neuen Release weiter Features. Nach und nach wird so der komplette Feature-Umfang über GraphQL abgebildet.

Features

Aktuell (Stand: Jänner 2021) unterstützt GraphQL diese Features:

Katalog

  • Produktlisten, -optionen und -konfigurationen
  • Empfohlene Produkte
  • Verknüpfte Produkte
  • Produktrabatte
  • Produkt-Bewertungen
  • Preise
  • Suchfunktionalität
  • Kategoriemenü
  • Filter-Navigation
  • Kategorie-Filter

Kunden-Account

  • Registrierung / Kunden-Account erstellen
  • Login und Logout
  • Passwort vergessen
  • Adressbuch
  • Purchase History
  • Alte Bestell-Daten inklusive Rechnungen, Versendungen und Gutschriften
  • Wunschlisten
  • Geschenkgutscheine (nur Magento Commerce)
  • Meine downloadbaren Produkte
  • Store Credits (nur Magento Commerce)

Warenkorb

  • Warenkorb erstellen, auslesen und bearbeiten
  • Preisberechnung im Warenkorb
  • Gutscheine
  • Produkte aller Produktarten hinzufügen
  • Geschenk-Gutscheine hinzufügen (nur Magento Commerce)
  • Rabatte

Checkout

  • Rechnungsadresse festlegen
  • Zahlungsart hinzufügen
  • Versandart festlegen
  • Bestellung abschicken

Beispiel: Checkout mit GraphQL implementieren

Die offizielle Dokumentation enthält ein Tutorial, mit dem man die Customer Journey und den Bestellvorgang komplett über GraphQL abbilden kann.

Folgende Schritte werden beschrieben:

  1. Kunde anlegen
  2. Einen leeren Warenkorb anlegen
  3. Produkte zum Warenkorb hinzufügen
  4. Versandadresse festlegen
  5. Rechnungsadresse festlegen
  6. Versandmethode festlegen
  7. Zahlungsart festlegen
  8. Gutscheincode anwenden
  9. Eine E-Mail-Adresse für den Warenkorb vergeben (nur bei Gast-Bestellungen)
  10. Bestellung abschicken

Roadmap

Eine offizielle, einfach im Web aufrufbare GraphQL-Roadmap gibt es nicht. Hier sind wichtige Eckpunkte mit Stand September 2020 (Quelle). Dabei habe ich Punkte entfernt, die erledigt sind.

Katalog (2. Hälfte 2020)

  • Staging & Preview (Magento Commerce)

Kunden-Account (2. Hälfte 2020)

  • Passwort zurücksetzen
  • Gespeicherte Zahlarten
  • Wiederbestellung
  • Versand- und Rechnungsdetails

Checkout (2. Hälfte 2020)

Diverses (1. Hälfte 2021)

Allgemein:

  • Katalog-Berechtigungen
  • Login als Kunde
  • Produkt-Vergleich
  • Retouren

Magento Commerce B2C:

  • Gift Registry
  • Reward Points

Magento Commerce B2B:

  • Company Management
  • Negotioable Contracts
  • Purchase Order workflow
  • QuickOrder
  • Requisition Lists
  • Shared Catalog

Informationen & Ressourcen für EntwicklerInnen

Eine umfassende Link-Liste zu Libraries für viele Programmier-Sprachen und Frameworks, Tools, Meetups und vieles mehr bietet die Awesome list of GraphQL & Relay.

Wer eine kurze und knackige Liste bevorzugt findet hier einige grundlegende Links, die mir den Einstieg in das Thema erleichtert haben.

Tools

Meine Lieblings-Tools für das Erkunden eines GraphQL-Schemas und das Entwickeln von GraphQL-Anfragen/Mutations sind:

Beide sind für Linux, MacOS und Windows verfügbar, Open Source und kostenlos. Sie sind übersichtlich, flexibel und bieten IDE-Features wie Auto-Completion.

Auch das beliebte Werkzeug Postman unterstützt GraphQL ab Version 7.2.

Konzeption einer GraphQL-Schnittstelle

Programmieren einer GraphQL-Schnittstelle

  • The Road to GraphQL: Das kostenlose E-Book umfasst ganze 350 Seiten und erklärt wichtige Konzepte und Basics zu GraphQL, Apollo Server / Apollo Client und React.
  • How to GraphQL: ein Fullstack-Tutorial, das mit Videos und Artikeln zu den Grund-Konzepten beginnt und danach Tutorials für verschiedene Software-Stacks wie React und Apollo oder node anbietet.