GraphQL ist eine Open-Source-Abfragesprache und serverseitige Laufzeit, die angibt, wie Clients mit Programmierschnittstellen (APIs) interagieren sollen.
GraphQL bietet eine effiziente, flexiblere Alternative zu Representational State Transfer (REST) und RESTful APIs und löst einige Einschränkungen von REST. Zum Beispiel die Möglichkeit, Ressourcen mit einer einzigen Abfrage genauer auszurichten.
GraphQL verwendet eine intuitive Syntax, die es Clients ermöglicht, eine einzige GraphQL-Abfrage an eine API zu senden und genau die benötigten Daten zu erhalten (anstatt auf komplexe Endgeräte mit vielen Parametern zuzugreifen). Diese effizientere Datenbeschaffung kann die Systemleistung verbessern und die Benutzerfreundlichkeit für Entwickler erhöhen.
Dadurch eignet sich GraphQL besonders für die Erstellung von APIs in komplexen Umgebungen mit sich schnell ändernden Anforderungen an das Front-End. Weder REST- noch GraphQL-APIs sind von Natur aus überlegen; es sind unterschiedliche Tools, die für unterschiedliche Aufgaben geeignet sind.
In den frühen 2010er Jahren erlebte Facebook ein enormes Wachstum und einen umfassenden Wandel. Doch die wachsende Nutzerbasis und zunehmend komplexe mobile App-Umgebung machten den bestehenden RESTful-Ansatz, dessen Kommunikation viel Hin und Her zu verschiedenen API-Endpunkten erforderte, um alle erforderlichen Abfragedaten abzurufen, unhaltbar.
REST APIs waren für den Umgang mit komplexen, datengesteuerten Benutzeroberflächen schlecht gerüstet und es kam häufig zu Latenzproblemen und Datenineffizienzen, insbesondere bei mobilen Benutzern mit begrenzten oder teuren Datentarifen.
Als Antwort auf diese Herausforderungen entwickelten Facebook-Ingenieure GraphQL (zusammen mit der Single-Page-Application-Plattform React) und veröffentlichten es 2015 als Open-Source-Lösung. Letztendlich übertrug Facebook den Dienst im Jahr 2018 auf die GraphQL Foundation, zu deren Mitgliedern Unternehmen wie AWS, Gatsby, Intuit und IBM gehören.
Die deklarativen Datenabruffunktionen einer GraphQL-Architektur drehen sich um mehrere Schlüsselkomponenten und -prozesse, die jeweils eine einzigartige Rolle bei der Datenverarbeitung spielen.
Dazu gehören:
GraphQL basiert auf einem starken Typsystem, bei dem alle Datentypen in der GraphQL-Schemadefinitionssprache (SDL) aufgezeichnet werden. Typisierte Schemata bestimmen die Datentypen, die in der API abgefragt werden können, sowie die Beziehungen zwischen den Typen und den Vorgängen, die dem Benutzer zur Verfügung stehen.
Mit anderen Worten: Sie definieren die Funktionen der API und die Form der Daten, mit denen Clients interagieren können. Die Konfiguration dieses Schemas bestimmt letztendlich, wie die API verwendet werden kann. Wenn Abfragen eingehen, wird das Schema zur Validierung der Abfrage verwendet und die GraphQL-API führt nur die validierten Abfragen aus.
Jedes Feld in einem Schema wird durch einen Resolver unterstützt, der Daten füllt und die Antwort auf eine Reihe von Feldern bestimmt. Resolver – die Daten aus einer Datenbank, einem Cloud-Service oder praktisch jeder anderen Quelle abrufen können – stellen Anweisungen zum Umwandeln einer GraphQL-Operation (z. B. einer Abfrage, Mutation oder eines Abonnements) in Daten bereit.
Wenn ein Abfragefeld gestartet wird, generiert das System einen Aufruf an den entsprechenden Resolver, um den nächsten Wert zu erzeugen. Wenn ein Feld einen Skalarwert erzeugt (z. B. eine Zeichenfolge oder Zahl), wird die Ausführung abgeschlossen. Wenn ein Feld einen Objektwert erzeugt, enthält die Abfrage weitere Felder für dieses Objekt. Dieser Vorgang wird fortgesetzt, bis nur noch Skalarfelder übrig sind.
Resolver erleichtern außerdem die Datenformatierung und helfen dem System, Informationen aus verschiedenen Datenquellen zusammenzuführen.
Eine Datenabfrage ist die Anfrage, die der Client an den GraphQL-Server stellt. Sie gibt an, welche Daten der Client abrufen möchte. Abfragen werden im Abfragetyp definiert, der ein spezielles Objekt im Code ist, das den Einstiegspunkt auf oberster Ebene für jede Anfrage definiert, die Clients an den Server senden können. Jeder Abfragetyp definiert auch den Namen und den Rückgabetyp für jeden Einstiegspunkt.
Wenn eine Abfrage eingeht, validiert GraphQL sie anhand der Schemadefinitionen und führt sie aus –vorausgesetzt, sie ist gültig. Die Struktur einer Abfrage spiegelt in der Regel die Struktur der Antwortdaten wider, was Datenanforderungen explizit und vorhersehbar macht.
Mutationen sind GraphQL-Vorgänge, die Daten auf dem Server erstellen, aktualisieren oder löschen. Sie sind analog zu den POST-, PUT-, PATCH- und DELETE-Vorgängen in RESTful-APIs. Während Benutzer ohne Authentifizierung auf einige Abfragen zugreifen können, erfordern Mutationen immer eine Authentifizierung (z. B. durch die Verwendung eines API-Tokens).
Ähnlich wie bei Abfragen werden GraphQL-Mutationen anhand des Schemas und seiner Definitionen validiert. Sobald die Mutation validiert und gestartet wurde, gibt der Server eine JSON-Antwort zurück.
Während GraphQL-APIs inzwischen als effizientere und flexiblere Alternative gelten, war REST lange Zeit der Standard für API-Architekturen. REST ist ein strukturierter Architekturstil für vernetzte Hypermedia-Anwendungen, der entwickelt wurde, um ein zwischenspeicherndes, zustandsloses Client/Server-Kommunikationsprotokoll (normalerweise HTTP) zu verwenden.
Bei der Entscheidung zwischen GraphQL und REST geht es hauptsächlich darum, zu bestimmen, welches Tool für die jeweilige Aufgabe am besten geeignet ist. Sowohl GraphQL als auch REST ermöglichen es Clients, mit Servern zu kommunizieren und Daten anzufordern, aber es gibt wesentliche Unterschiede, die die Verbreitung von GraphQL-Systemen erklären.
REST-APIs sind auf Ressourcen ausgerichtet (z. B. jede Art von Objekt, Daten oder Dienst, auf den der Client zugreifen kann) und funktionieren, indem sie für jede Ressource unterschiedliche Endpunkte (URLs) aufweisen. Sie verwenden eine feste Datenstruktur, um die Form und Größe der Ressourcen zu bestimmen, die sie ihren Kunden bereitstellen.
Wenn der Client eine Ressource anfordert, sendet der Server einen vollständigen Datensatz mit allen Daten zurück, die mit dieser Ressource verknüpft sind. Auch wenn ein Client nur eine Teilmenge der Daten benötigt, empfängt er trotzdem alle Daten (Overfetching); wenn er hingegen Daten benötigt, die mehrere Ressourcen umfassen, muss er oft mehrere API-Aufrufe tätigen, da die Daten der ursprünglichen Anfrage nicht ausreichen (Unterabruf).
GraphQL verwendet dagegen einen einzelnen Endpunkt, der eine vollständige und verständliche Beschreibung der Daten bereitstellt. GraphQL-Abfragen können auf Ressourceneigenschaften zugreifen und Referenzen zwischen Ressourcen verfolgen. Dadurch kann der Kunde alle benötigten Daten aus einer einzigen API-Anforderungsnutzlast abrufen und Probleme durch zu viele oder zu wenige Abrufe vermeiden.
In einer RESTful-Architektur müssen Teams bei einer Änderung der Datenstruktur oft die API versionieren, um Systemfehler und Serviceunterbrechungen für den Nutzer zu vermeiden.
Das bedeutet, dass Entwickler jedes Mal, wenn sie die Struktur ändern, einen neuen Endpunkt erstellen müssen, was zu mehreren API-Versionen führt und den Wartungsprozess erschwert.
GraphQL macht Versionierung überflüssig, da Clients ihre Anforderungen in der Abfrage angeben können. Wenn dem Server neue Felder hinzugefügt werden, sind Clients, die diese Felder nicht benötigen, davon nicht betroffen. Wenn Felder hingegen veraltet sind, können Clients sie weiterhin anfordern, bis sie ihre Abfragen aktualisieren.
REST-APIs verwenden HTTP-Statuscodes, um den Status/Erfolg einer Anfrage anzuzeigen. Jeder Statuscode hat eine bestimmte Bedeutung. Bei einer erfolgreichen Anfrage wird der Statuscode 200 zurückgegeben, während ein Client-Fehler den Statuscode 400 und ein Server-Fehler den Statuscode 500 erzeugen kann.
GraphQL behandelt Fehler unterschiedlich. Jede Anfrage gibt unabhängig davon, ob sie zu einem Fehler geführt hat, einen Statuscode 200 OK zurück. Die Fehler werden nicht über HTTP-Statuscodes kommuniziert; stattdessen kommuniziert das System Fehler im Antworttext zusammen mit den Daten.
Bei diesem Ansatz müssen Clients den Antworttext analysieren, um festzustellen, ob die Anfrage erfolgreich war. Das kann das Debuggen von GraphQL-APIs erschweren.
REST bietet keine integrierte Unterstützung für Echtzeit-Updates. Wenn eine Web- oder Mobilanwendung Echtzeitfunktionen mit einer REST-API benötigt, müssen Entwickler in der Regel Techniken wie Long-Polling (bei dem der Client den Server wiederholt nach neuen Daten abfragt), vom Server gesendete Ereignisse und WebSockets implementieren, was die Anwendung komplexer machen kann.
GraphQL bietet dagegen integrierte Unterstützung für Echtzeit-Updates durch den Einsatz von Abonnements. Abonnements halten eine stabile Verbindung zum Server aufrecht, sodass der Server bei bestimmten Ereignissen Aktualisierungen an den Client weiterleiten kann und Clients den Überblick über relevante API-Daten behalten.
Das REST-Ökosystem ist gut etabliert und bietet Entwicklern eine breite Palette an Tools, Bibliotheken, Frameworks und Tutorials. Bei der Arbeit mit REST-APIs müssen Teams jedoch häufig durch mehrere Endpunkte navigieren und die einzigartigen Konventionen und Muster jeder API kennen.
GraphQL ist relativ neu, aber das GraphQL-Ökosystem ist seit seiner Einführung enorm gewachsen und bietet eine Vielzahl von Tools und Bibliotheken für die Entwicklung von Frontend- und Backend-Diensten.
Tools wie GraphiQL, Apollo Studio und GraphQL Playground bieten leistungsstarke integrierte Entwicklungsumgebungen (IDEs) im Browser zum Erkunden und Testen von GraphQL-APIs. Darüber hinaus bietet GraphQL eine starke Unterstützung für die Codegenerierung, was die Entwicklung auf der Clientseite vereinfachen kann.
REST-APIs basieren auf HTTP-Caching-Mechanismen wie ETags und zuletzt geänderten Headern. Caching-Strategien sind zwar effektiv, aber eventuell umständlich zu implementieren und optimieren die Leistung nicht immer für alle Anwendungsfälle.
Das Zwischenspeichern von GraphQL-APIs kann aufgrund der dynamischen Natur der Abfragen schwieriger sein. Der Einsatz von persistierten Abfragen, Response Caching und Server-seitigem Caching kann diese Herausforderungen jedoch entschärfen und effiziente Caching-Strategien für GraphQL-Architekturen bieten.
Seit der Übernahme von GraphQL in die GraphQL Foundation haben Entwickler unter anderem Implementierungen für verschiedene Programmiersprachen wie JavaScript, Python, Ruby und PHP erstellt. GraphQL-APIs wurden von zahlreichen Unternehmen wie Github, Pinterest, PayPal, Shopify, Airbnb und anderen übernommen, was es immer mehr Kunden ermöglicht, Datenspezifikationen zu vereinfachen, übermäßige oder unzureichende Netzwerkdatenübertragungen zu reduzieren und die allgemeinen Datenabrufmöglichkeiten zu verbessern.1
Darüber hinaus drängen Unternehmen und Entwickler auf eine offene Föderation von GraphQL-Architekturen. In seiner aktuellen Iteration nimmt der GraphQL-Verbund separate GraphQL-Dienste auf und fasst sie in einer einzigen GraphQL-API zusammen, die als Einstiegspunkt für alle zugrunde liegenden Backend-Daten dient und den Datenabruf durch eine einzige Anfrage erleichtert. Die Umsetzung durch die Föderation ist jedoch einem einzigen Anbieter vorbehalten.
Als Reaktion darauf setzen sich die Befürworter von GraphQL für eine demokratisierte Föderation ein, die die Datenaggregation sowohl von GraphQL-APIs als auch von Nicht-GraphQL-APIs erleichtert, anstatt eine ausschließlich auf GraphQL basierende Aggregation zu ermöglichen.2
Ermöglichen Sie eine dynamische, skalierbare Integration, die sich an sich ändernde Geschäftsanforderungen anpasst. KI-gestützte, API-basierte Automatisierung
Erschließen Sie Ihr Geschäftspotenzial mit IBM Integrationslösungen, die Anwendungen und Systeme für den schnellen und sicheren Zugriff auf wichtige Daten verbinden.
Nutzen Sie das volle Potenzial der Hybrid Cloud im Zeitalter der agentischen KI
1 IBM acquires GraphQL startup StepZen to step up its game in API Management, TechCrunch, 8. Februar 2023
2 Why GraphQL Needs an Open Federation Approach, The New Stack, 16. November 2023