GraphQL: Flexible Abfragesprache und Laufzeitumgebung für Ihr Web-API
Anwendungen im Web nutzen APIs (Application Programming Interfaces), um Daten auszutauschen und weiterzuverarbeiten. Sollen also andere Services auf Daten Ihres Webprojekts zugreifen können, müssen Sie eine solche Schnittstelle entwickeln und implementieren. Wie so oft gibt es auch hierfür einige etablierte Standards wie SOAP oder REST (Representational State Transfer), die eine Grundstruktur für Ihr API vorgeben, die mit jeder gängigen Programmiersprache problemlos angesteuert werden kann – insbesondere letztgenannte Architektur hat sich aufgrund ihrer Simplizität in den vergangenen Jahren zur absoluten Premium-Lösung entwickelt.
Doch auch wenn der Siegeszug der REST-Architektur durchaus beeindruckend ist, gibt es dennoch interessante Alternativen wie GraphQL, die ebenfalls zu überzeugen wissen. Die Abfragesprache und Laufzeitumgebung aus dem Hause Facebook kann durchaus mit SOAP und REST mithalten, wobei ihre Vorzüge unter anderem bei komplexeren Abfragen zum Tragen kommen.
- DNS-Management
- SSL-Verwaltung
- API-Dokumentation
Was ist GraphQL?
GraphQL ist eine 2012 von Facebook entwickelte, SQL-ähnliche Abfragesprache inklusive Laufzeitumgebung und Typsystem. Ursprünglich war sie ausschließlich für den unternehmensinternen Einsatz vorgesehen. Hintergrund war die Umgestaltung der nativen mobilen Facebook-Apps für iOS und Android, die aufgrund steigender Komplexität zunehmend schwächere Performance zeigten. Insbesondere für die Auslieferung der Newsfeed-Daten musste der Großkonzern eine adäquate Lösung finden, bei der das Verhältnis zwischen abgerufenen Informationen und notwendigen Serverabfragen zufriedenstellend war. 2015 machte Facebook den GraphQL-Quellcode frei verfügbar – zu diesem Zeitpunkt regelte er fast schon den gesamten Datenzugriff der mobilen Apps. Seit 2017 läuft das Projekt unter der freien OWFa-1.0-Lizenz (Open Web Foundation).
So funktioniert GraphQL
Um die Funktionsweise von GraphQL zu verstehen, ist es notwendig, sich mit den drei elementaren Komponenten auseinanderzusetzen, die das Open-Source-Projekt auszeichnen:
- Abfragesprache: In erster Linie beschreibt das GraphQL-Konzept eine Abfragesprache (Query Language), die Programmen den unkomplizierten Zugriff auf ein API ermöglicht. Während andere Schnittstellen-Architekturen nur sehr strikte Abfragen ermöglichen, die oft lediglich den Zugriff auf eine einzelne Ressource gewähren, zeichnen sich GraphQL-Querys durch ein hohes Maß an Flexibilität aus. Diese zeigt sich konkret darin, dass es keine Limitierung für die Zahl abgefragter Ressourcen gibt, und dass gezielt definiert werden kann, welche Datenfelder abgefragt werden sollen. GraphQL erlaubt dabei sowohl lesende als auch schreibende bzw. verändernde Abfragen vor.
- Typsystem: GraphQL arbeitet außerdem mit einem eigenen Typsystem, das es Ihnen erlaubt, Ihr API durch Datentypen zu beschreiben. Die auf diese Weise definierten Datenstrukturen schaffen dann den eigentlichen Rahmen für Abfragen. Jeder Typ besteht dabei aus einem oder mehreren Feldern, die wiederum eigene Typangaben enthalten. Das auf diese Weise geschaffene, individuelle System dient GraphQL dann als Orientierungspunkt, um Anfragen validieren und fehlerhafte Querys ablehnen zu können.
- Laufzeitumgebung: Schließlich liefert GraphQL auch verschiedene Server-Laufzeitumgebungen zum Ausführen der GraphQL-Abfragen. Zu diesem Zweck stehen Bibliotheken für diverse Programmiersprachen zur Verfügung – beispielsweise Go, Java, JavaScript, PHP, Python oder Ruby. Sie haben also nahezu freie Wahl hinsichtlich der Sprache Ihres persönlichen GraphQL-APIs. Die Laufzeitumgebung ist allerdings ausschließlich für die Umwandlung (Parsen) und Validierung der Abfragen sowie für die Serialisierung der Antworten (Umwandlung der Objekte in eine entsprechende Bytefolge) verantwortlich. Das Speichern und Ermitteln der Daten (z. B. in einer Datenbank) gehört zum Aufgabenbereich Ihrer Webanwendung.
Im Zusammenspiel sorgen Abfragesprache, Typsystem und Laufzeitumgebung für ein hochgradig wandelbares API-Gerüst. Das ist nicht nur plattform- und anwendungsübergreifend zugänglich, sondern lässt sich auch perfekt auf die Eigenheiten Ihrer Webapplikation abstimmen: Sie können die GraphQL-Schnittstelle also problemlos in den Code Ihres Projekts integrieren – unabhängig davon, ob Sie beispielsweise das Python-Framework Django, das Ruby-Framework Rails oder das JavaScript-Framework Node.js nutzen.
Was zeichnet GraphQL aus?
Eines der Hauptmerkmale von GraphQL ist die Simplizität der Abfragesprache, die Entwicklern den Zugang zur Schnittstelle so einfach wie möglich macht. Wer sich mit GraphQL auseinandersetzt, der wird beispielsweise schnell feststellen, dass erhaltene Antworten eins zu eins die gestellten Abfragen widerspiegeln. Ausgabeformat ist dabei das gleichermaßen schlanke wie verbreitete JavaScript-Format JSON (JavaScript Object Notation). Folglich ist das Verschicken einer passgenauen Abfrage keine große Herausforderung, sofern Sie die Struktur der Daten kennen, die Ihre Anwendung benötigt, und diese in der Query formulieren. Zusätzlich zur einfachen Erstellung von Abfragen zeichnet sich GraphQL insbesondere durch folgende Eigenschaften aus:
- Hierarchische Struktur: Datenbestände, die über GraphQL-APIs abrufbar sind, haben eine hierarchische Struktur. Automatisch lassen sich Beziehungen zwischen den einzelnen Objekten erzeugen, auf deren Basis auch komplexe Anfragen in einem einzigen Request formuliert (und beantwortet) werden können. Ein Austausch mehrerer Nachrichten zwischen Server und Client (auch „Round Trips“ genannt) ist nicht notwendig. Diese Datenhierarchie ist insbesondere für graphenorientierte Datenbanken wie JanusGraph geeignet und für Benutzer-Interfaces, die meist ebenfalls hierarchisch aufgebaut sind.
- Starke Typisierung: Jede Ebene einer GraphQL-Abfrage entspricht einem bestimmten Typ, wobei jeder Typ ein Set verfügbarer Felder beschreibt. Dieses Typsystem kann allerdings noch mehr als automatisch feststellen, ob eine Abfrage korrekt oder nicht korrekt formuliert ist: Denn wie SQL kann auch GraphQL dank der strikten Typisierung bereits während der Entwicklung bzw. vor Abschicken der Query beschreibende Fehlermeldungen ausspielen.
- Flexibilität: GraphQL ermöglicht Ihnen, flexible Abfragen zu starten. Darüber hinaus eröffnet es Ihnen aber auch eine Reihe von Freiheiten und Vorteilen bei der Entwicklung bzw. Anpassung Ihrer Schnittstelle. So sind serverseitig in der Regel nur wenige Anpassungen vorzunehmen, wobei das Entwicklerteam vollkommen unabhängig von dem Team agieren kann, das für die Client-Komponente verantwortlich ist. Ferner können sämtliche Veränderungen oder Erweiterungen des APIs ohne Versionierung durchgeführt werden, da sich zusätzliche Felder problemlos und ohne Beeinträchtigung existierender Clients hinzufügen lassen.
GraphQL vs. REST – Was unterscheidet die beiden API-Konzepte?
Eingangs ist der große Erfolg von REST im World Wide Web bereits ebenso zur Sprache gekommen wie die Tatsache, dass GraphQL eine ernstzunehmende Alternative zu dieser etablierten HTTP-basierten und ressourcenorientierten Architektur für Webservices ist. Möglich gemacht hat das insbesondere eine Entwicklung, die Facebook überhaupt erst zu der Konzipierung von GraphQL bewegt hat: Die steigende Bedeutung und zunehmende Komplexität mobiler Webapplikationen – denn insbesondere bei diesen Anwendungen für Android, iOS und Co. zeigt sich die große Stärke von GraphQL als API-Basis: Man kann mit einer einzigen Query Zugriff auf alle gewünschten Daten erhalten.
Die GraphQL-Serverinstanz liefert dabei exakt die in der Abfrage definierten Informationen aus, sodass weder mehr noch weniger Daten als benötigt über die Schnittstelle versendet werden. Bei vergleichbaren REST-APIs können Sie immer nur einen bestimmten Datensatz pro Query abfragen, woraufhin dieser komplett ausgegeben wird. Im direkten Vergleich „GraphQL vs. REST“ erweist sich das Abfragekonzept von Facebook als wesentlich präziser und effizienter, was der Performance Ihrer Applikation zugutekommt. Diese zahlt sich wiederum insbesondere für Nutzer mobiler Geräte aus, denen oft nur leistungsschwächere Internetverbindungen zur Verfügung stehen.
Während aus der Freiheit bei der Datenabfrage von GraphQL einerseits viele positive Merkmale resultieren, kann sie andererseits jedoch auch zum ernsthaften Sicherheitsproblem werden: Vor allem, wenn Sie offene APIs anbieten wollen, bei denen Sie das Abfrageverhalten von Drittanbieter-Clients nicht kontrollieren können. So ist es möglich, dass eine zu hohe Zahl an Querys den Server zum Absturz bringt (absichtlich oder unabsichtlich). Ein derartiges Szenario, vor dem Sie sich entsprechend schützen müssen, droht Ihnen beim Einsatz einer REST-API nicht so schnell. GraphQL im Backend so umzusetzen, dass es performant und sicher läuft, ist also wesentlich schwieriger.
Zudem ist auch die Implementierung eines Caching-Verfahrens für nicht veränderliche Abfragen mit GraphQL erheblich komplizierter als für Abfragen über eine REST-Schnittstelle. Letztere lassen sich durch die Caching-Methoden der HTTP-Spezifikation zwischenspeichern (beispielsweise im Browser).
GraphQL-Tutorial: Einstieg und GraphQL-Beispiel
GraphQL lässt Ihnen dank des großen Angebots an einsatzbereiten Bibliotheken großen Spielraum bei der Wahl der zugrundeliegenden Programmiersprache. Das ist auch einer der großen Vorzüge bei der Implementierung einer GraphQL-Schnittstelle in Ihre App. So können Sie beispielsweise als Python-Fan auf die Graphene-Bibliothek zurückgreifen – oder mit der Bibliothek graphql-java arbeiten, wenn Ihr Projekt auf Java basiert. Stützt sich Ihre Webanwendung auf die JavaScript-Laufzeitumgebung Node.js, eignet sich unter anderem GraphQL.js als Basis für die Implementierung.
Eine Auflistung verfügbarer GraphQL-Bibliotheken und Client-Anwendungen für diverse Programmiersprachen finden Sie auf der offiziellen GraphQL-Homepage.
Im folgenden GraphQL-Tutorial erläutern wir Ihnen exemplarisch den Einstieg und die ersten Schritte mit dem API-Framework für eine JavaScript-Anwendung, wobei zusätzlich zur letztgenannten GraphQL.js-Bibliothek auch das Web-Framework Express zum Einsatz kommt.
Schritt 1: Installation der Bibliothek
Um GraphQL-Bibliotheken nutzen zu können, müssen Sie diese zunächst installieren. Bei der JavaScript-Bibliothek GraphQL.js nutzen Sie dafür den JavaScript-Paketmanager npm (Node Package Manager) und folgenden Befehl:
npm install --save graphql
Alternativ können Sie die Bibliothek auch über den unter anderem von Facebook (überwiegend) und Google entwickelten Paket- und Abhängigkeitsmanager Yarn beziehen:
yarn add graphql
Voraussetzung ist in beiden Fällen natürlich, dass eine aktuelle Version von Node.js installiert ist (empfohlen: Node v6.0.0 oder höher).
Schritt 2: Das erste Abfrage-Schema
Damit Ihre Anwendung GraphQL-Abfragen verarbeiten kann, benötigen Sie ein Schema, das den Typ „Query“ (also Abfrage) definiert sowie den Zugangspunkt zu Ihrer Schnittstelle (auch API-Root genannt) inklusive Resolver-Funktion. Für eine einfache GraphQL-Beispiel-Schnittstelle, die lediglich die Nachricht „Hallo Welt!“ ausgibt, sähe der passende Code in der zu diesem Zweck angelegten Datei server.js folgendermaßen aus:
var { graphql, buildSchema } = require('graphql');
// Konstruiere Schema auf Basis des GraphQL-Konzepts
var schema = buildSchema(`
type Query {
hello: String
}
`);
// API-Root stellt eine Resolver-Funktion für jeden zugreifenden Endpunkt zur Verfügung
var root = {
hello: () => {
return 'Hallo Welt!';
},
};
// Führe GraphQL-Abfrage '{ hello }' aus und spiele entsprechende Antwort aus
graphql(schema, '{ hello }', root).then(response => {
console.log(response);
});
Führen Sie diesen Code nun mit Node.js aus, indem Sie den Befehl
node server.js
in das Terminal eingeben, sollten Sie folgende Nachricht erhalten:
{ data: { hello: 'Hallo Welt!' } }
Schritt 3: Der eigene GraphQL-Server auf Express-Basis
Nachdem Sie im vorangegangenen Schritt eine einfache Abfrage erstellt und über die Kommandozeile ausgeführt haben, ist es nun an der Zeit, einen GraphQL-API-Server zum Laufen zu bringen. Dadurch lässt sich die Schnittstelle beispielsweise über einen gewöhnlichen Webbrowser erreichen. Zu diesem Zweck installieren Sie zunächst das eingangs erwähnte Applikations-Framework Express sowie die ebenfalls benötigte Bibliothek express-graphql mit folgendem Befehl:
npm install express express-graphql --save
Anschließend modifizieren Sie das „Hallo Welt”-GraphQL-Beispiel so, dass es anstelle eines einfachen Skripts zur Basis Ihres GraphQL-Servers wird. Zu diesem Zweck implementieren Sie das Express-Modul und nutzen die express-graphql-Bibliothek, um den API-Server am HTTP-Endpunkt „/graphql“ einzubinden:
var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Konstruiere Schema auf Basis des GraphQL-Konzepts
var schema = buildSchema(`
type Query {
hello: String
}
`);
// API-Root stellt eine Resolver-Funktion für jeden zugreifenden Endpunkt zur Verfügung
var root = {
hello: () => {
return 'Hallo Welt!';
},
};
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true
}));
app.listen(4000);
console.log('GraphQL-API-Server auf localhost:4000/graphql ausführen');
Wie im vorigen GraphQL-Beispiel öffnen Sie die server.js-Datei nun mit Node.js – mit dem Unterschied, dass Sie dieses Mal nicht eine einfache Abfrage ausführen, sondern Ihren API-Server starten:
node server.js
Im Code des GraphQL-Express-Servers sind nicht nur Schema und Root-API spezifiziert, sondern es ist auch der HTTP-Endpunkt „/graphql“ aufgeführt. Durch den Eintrag „graphiql: true“ ist unter anderem das gleichnamige Tool aktiviert worden, das Ihnen die Eingabe von Querys über ein grafisches Benutzer-Interface ermöglicht. Öffnen Sie dazu einfach Ihren Browser und geben Sie die folgende Adresse ein:
http://localhost:4000/graphql
Nachdem Sie in den verschiedenen Schritten dieses GraphQL-Tutorials die notwendigen Komponenten installiert, Ihr erstes Abfrage-Schema erstellt und den eigenen Server gestartet haben, können Sie sich danach also in aller Ruhe mit den Query-Eingabemöglichkeiten vertraut machen.
Weitere Informationen hierzu sowie ausführliche Erklärungen zur Gestaltung von GraphQL-Backends und -Frontends finden Sie im Tutorialbereich auf der offiziellen Homepage des Facebook-API-Konzepts.