Bei GraphQL gibt es typischerweise nur einen Endpunkt. Statt mehrerer fester REST-Routen schickt der Client eine Abfrage, die exakt die gewünschten Felder beschreibt, und erhält eine Antwort in derselben Struktur zurück. Dadurch holt er weder zu viele noch zu wenige Daten und kann verschachtelte, zusammenhängende Objekte in einer einzigen Anfrage traversieren, statt mehrere Roundtrips wie im klassischen REST-Ansatz zu machen.
Grundlage ist ein starkes Typsystem: Das Schema wird in der Schema Definition Language (SDL) beschrieben und legt fest, welche Typen, Felder und Argumente es gibt. Jedes Feld kann eigene Argumente bekommen, und die Antwort hat immer die gleiche Form wie die Anfrage. Ergebnisse liegen unter einem Schlüssel data, Fehler unter errors.
GraphQL kennt drei Operationstypen:
- Query: Daten lesen.
- Mutation: Daten schreiben, also anlegen, ändern oder löschen.
- Subscription: Echtzeitdaten, der Server pusht Aktualisierungen an den Client.
Praktische Bausteine sind unter anderem Variablen (dynamische Werte mit $name statt String-Interpolation), benannte Operationen für besseres Logging und Debugging, sowie Fragmente, um wiederkehrende Feldmengen wiederzuverwenden.
Vorteile:
- Hohe Flexibilität, der Client bestimmt die Felder.
- Verschachtelte Daten in einer einzigen Anfrage statt vieler Roundtrips.
- Schema und Typsystem dienen als Vertrag und ermöglichen Validierung sowie Introspektion.
Nachteile und Stolpersteine:
- Caching ist schwieriger als bei REST, weil meist ein Endpunkt per POST genutzt wird statt vieler cachebarer URLs.
- Mehr Komplexität auf der Serverseite, etwa durch Resolver, Autorisierung pro Feld und Schema-Pflege.
- Das N+1-Problem: verschachtelte Felder können viele Einzelabfragen auslösen, was Batching und Caching (zum Beispiel Dataloader) nötig macht.
Typischer Einsatz: datenhungrige Frontends und Mobile-Apps, die viele zusammenhängende Daten effizient laden wollen, sowie Szenarien, in denen viele unterschiedliche Clients eigene Sichten auf dieselben Daten brauchen.
query HeroNameAndFriends($episode: Episode = JEDI) {
hero(episode: $episode) {
name
friends {
name
}
}
}Eine Query mit Variable und verschachtelten Feldern: ein Held und die Namen seiner Freunde werden in einer einzigen Anfrage geladen. Der Default JEDI erlaubt den Aufruf auch ohne übergebene Variable.
Quellen
- Learn GraphQL GraphQL Foundation (graphql.org)
- Queries GraphQL Foundation (graphql.org)