
Was ist eigentlich GraphQL? (Bild: Game art assets/Shutterstock)
GraphQL ist – wie der Name vermuten lässt – eine Abfragesprache zum Auslesen und Manipulieren von Daten in API und erfreut sich vor allem seitdem sie 2015 Open Source wurde steigender Beliebtheit. So groß der Hype sein mag und so sehr die Vorteile auf der Hand liegen mögen, gibt es natürlich Anwendungsfälle, in denen Entwickler mit Rest möglicherweise besser bedient sind. Für kleinere Nebenprojekte lohnt sich allein der Aufwand, GraphQL zu lernen, wohl nur bedingt. Für größere Anwendungen, auf die verstärkt von Geräten mit mobiler Datenverbindung zugegriffen wird, dürfte GraphQL aber in vielen Fällen eine sehr gute Wahl sein. Unser Artikel liefert einen Überblick über die wichtigsten Fakten und Vorteile der Abfragesprache.
So funktionierts:
Backend-Entwickler können Daten im GraphQL Typensystem in einem sogenannten GraphQL-Schema beschreiben:
schema.gql
type Magazine {
id: ID!
title: String!
pages: Number
Authors: [Author]
}
Frontend-Consumer können die API dann durchsuchen und nur jene Daten anfordern, die sie tatsächlich brauchen.
Offensichtlich anders als Rest
Traditionell haben Webentwickler via Rest auf API zugegriffen, wo via http-Methoden auf Daten, die auf einem Server liegen, zugegriffen werden kann. Bei einem Request beinhaltet die API-Response den kompletten Data-Payload der angefragten Entität.
client – Request: GET magazine – 📰 server
client – Request: GET rocket – 🚀 server
client – Request: GET planet – 🪐 server
So weit, so gut. Dieser Ansatz bringt allerdings zwei mögliche Nachteile mit sich. Möglicherweise werden mehrere unterschiedliche Entitäten auf einmal benötigt. Die können aber nur in vielen einzelnen Requests abgerufen werden. Das bedeutet, auch für das Rendern simpler Frontends braucht es multiple Requests an sehr viele ausdifferenzierte Endpunkte. Das ist besonders ungünstig, wenn es sich um einen mobilen Client mit einer langsamen Internetverbindung handelt. In anderen Fällen wird vielleicht nur ein kleiner Teil Daten aus einer Entität benötigt. Zum Beispiel nur die E-Mailadresse eines Users und nicht auch noch seine Adresse, sein Geburtsdatum und seine Telefonnummer. Mit Rest kann aber immer nur das gesamte Item mit allen zugehörigen Daten gefetched werden, auf Teildaten einer Entität zuzugreifen, und nur diese abzurufen, ist nicht möglich. Rest API sind für Server optimiert, nicht notwendigerweise für Clients. Sie sind quasi um die Ressourcen herum modelliert – das macht sie überall einsetzbar und von Client zu Client nutzbar. Genau das ist eine von Rests größten Stärken. Damit einher geht aber auch, dass eine öffentliche API per definitionem sehr generisch sein muss. Damit Dritte darauf aufbauend Plugins, Integrationen und Extensions bauen können, muss sie so aufgebaut sein, dass sie keine Vorannahmen darüber trifft, wie die darin enthaltenen Daten genutzt werden.
In GraphQL können Frontend-Entwickler Datenabfragen in einem Format beschreiben, dessen Syntax ihre Rückgabeform in JSON widerspiegelt, nur ohne die Values. Frontend-Entwicker beschreiben die Daten, die sie benötigen, und Backend-Entwickler schreiben Code, um den Request aufzulösen. GraphQL ist programmiersprachenagnostisch. Ob eine Applikation Python, Rust, oder Go auf Serverseite oder Kotlin, JavaScript oder Swift auf Clientseite verwendet, spielt keine Rolle.
So ist eine GraphQL-API aufgebaut:
Via des type
-Keywords lässt sich GraphQL ein Schema mit eigenen, benutzerdefinierten Objekten definieren. Ein solcher type kann über mehrere Felder, auch fields genannt, verfügen:
type Author {
id: ID!
name: String
subscribers: Integer
articles: [Article]
}
Das ! hinter der ID im Beispiel macht dieses Feld required, es muss also ein Wert vorhanden sein. Das Schema verfügt außerdem über Integer und String-Values und steht in Beziehung zu einem anderen benutzerdefinierten Objekt, im Beispiel article. Ein Autor kann mehrere Artikel geschrieben haben. Die Gesamtheit der Artikel eines Autors kann mithilfe von [] referenziert werden.
Umgekehrt ist jeder Artikel einem Autor oder einer Autorin zuzuordnen:
type Article {
url: String
creator: Creator
}
Jede GraphQL-API verfügt über einen Query
-Type:
type Query {
articles: [Article]
authors: (id: String!) : Author
}
So können Konsumenten der API die Daten einsehen. Damit sie außerdem die Möglichkeit haben, die Daten zu bearbeiten, können Entwickler einer GraphQL-API einen Mutation
-Type implementieren. Dieser definiert, wie Daten auf der API modifiziert werden können:
type Mutation {
createArticle(url: String) : Video
deleteArticle(url: String) : String
}
Davon ausgehend können Entwickler diese Daten mittels Code in einer beliebigen Programmiersprache auflösen, hier mittels JavaScript:
//resolver.js
export const resolvers = {
Query: {
creator(obj, args, context, info) {
return context
.db
.getAuthor(args.id);
},
},
};
Einmal deployed, können Entwickler die API einsehen, inklusive aller vorhandenen Daten und aller möglichen Abfragen.
Wer sich für die Entstehung von GraphQL interessiert – darüber hat Honeypot 2019 eine sehenswerte Doku veröffentlicht. Für einen tieferen Einstieg in die Thematik gab es 2018 einen t3n-Magazinartikel zum Thema.