GraphQL oder REST: Welche Datenabfrage zu Ihrem Projekt passt

Wie GraphQL Daten abfragt, wo es REST überlegen ist und an welchen Stellen der Aufwand für Caching, Sicherheit und Betrieb steigt
Aktualisiert:
Abstract
- #GraphQL
- #RESTful APIs
- #API-Entwicklung
- #Queries
- #Mutations
- #Schema-Definition
- #Resolver
- #Versionierung
- #Performance-Optimierung
- #Caching
Eine Abfragesprache gegen ein bewährtes Architekturprinzip – warum die Antwort selten „entweder oder“ lautet
Eine Produktseite in einem Webshop braucht auf den ersten Blick wenig: Name, Preis, Bilder, Verfügbarkeit, ein paar Bewertungen und drei ähnliche Artikel. Hinter dieser Seite stecken bei einer klassischen REST-Schnittstelle aber oft fünf oder sechs Anfragen an verschiedene Adressen – und jede liefert mehr Felder zurück, als die Seite tatsächlich anzeigt. Auf dem Smartphone im Zug merkt man das.
Genau an diesem Punkt setzte GraphQL an, als Facebook die Abfragesprache 2015 öffentlich machte. Seitdem wird regelmäßig verkündet, GraphQL werde REST ablösen. Das ist nicht passiert, und es wird in dieser Form auch nicht passieren. Beide Ansätze haben sich in unterschiedlichen Nischen festgesetzt. Die interessante Frage ist deshalb nicht, welcher besser ist, sondern welcher für welches Problem.
Zwei Denkweisen: Ressourcen gegen Abfragen
REST ist ein Architekturstil, der Daten als Ressourcen mit eigener Adresse beschreibt: /produkte/42, /produkte/42/bewertungen. Was eine Ressource zurückgibt, legt der Server fest. Die Grundlagen dazu – HTTP-Methoden, Statuscodes, Aufbau von Anfragen – erklärt unser Beitrag RESTful APIs verständlich erklärt. Hier geht es um den Vergleich.
GraphQL dreht die Verantwortung um. Es gibt in der Regel nur eine Adresse, etwa /graphql, und der Client schickt eine Abfrage, die genau beschreibt, welche Felder er haben möchte. Der Server antwortet mit einem JSON-Dokument, das dieselbe Form hat wie die Abfrage. Wer nur Name und Preis anfragt, bekommt nur Name und Preis.
Ein Vergleich aus dem Büroalltag: REST ist wie ein Aktenschrank mit beschrifteten Ordnern. Sie ziehen einen Ordner und bekommen ihn komplett. GraphQL ist eher wie eine Kollegin im Archiv, der Sie einen Zettel geben: „Aus Ordner A Seite 3, aus Ordner B die Unterschrift.“ Sie bekommen genau das, aber die Kollegin muss dafür mehr Arbeit leisten.
Was beim Over- und Underfetching wirklich passiert
Zwei Begriffe tauchen in jedem Vergleich auf. Overfetching heißt, dass eine Antwort mehr Daten enthält, als der Client braucht – etwa die komplette Produktbeschreibung samt Lieferantendaten, obwohl die Listenansicht nur Name und Preis zeigt. Underfetching heißt, dass eine Antwort zu wenig enthält und weitere Anfragen nötig werden, etwa für Bewertungen und Lagerbestand.
GraphQL löst beides auf Protokollebene. Eine einzige Abfrage kann Produkt, Bewertungen und Empfehlungen zusammen holen:
query Produktseite($id: ID!) {
produkt(id: $id) {
name
preis
verfuegbar
bewertungen(erste: 3) {
sterne
text
}
aehnlicheProdukte(anzahl: 3) {
name
preis
}
}
}
Allerdings lässt sich dasselbe Problem auch mit REST entschärfen: durch gezielte Endpunkte für einzelne Ansichten, durch Parameter zur Feldauswahl oder durch ein sogenanntes Backend for Frontend, eine kleine Zwischenschicht, die Daten für genau eine Oberfläche zusammenstellt. Der Vorteil von GraphQL ist also weniger, dass es ein unlösbares Problem löst, sondern dass es eine einheitliche, standardisierte Lösung dafür bietet.
Schema, Resolver und Mutations: So arbeitet GraphQL
Das Herzstück jeder GraphQL-API ist das Schema. Es beschreibt in einer eigenen, gut lesbaren Sprache alle Typen, Felder und Beziehungen. Das Schema ist der Vertrag zwischen Frontend und Backend: Was dort nicht steht, kann niemand abfragen.
type Produkt {
id: ID!
name: String!
preis: Float!
verfuegbar: Boolean!
bewertungen(erste: Int = 10): [Bewertung!]!
altePreisangabe: String @deprecated(reason: "Bitte preis verwenden")
}
type Bewertung {
sterne: Int!
text: String
}
type Query {
produkt(id: ID!): Produkt
}
type Mutation {
bewertungAnlegen(produktId: ID!, sterne: Int!, text: String): Bewertung!
}
Das Ausrufezeichen bedeutet, dass ein Feld nie leer sein darf. Weil der Server das Schema kennt, prüft er jede Abfrage, bevor er sie ausführt. Fragt ein Client nach einem Feld, das es nicht gibt, lehnt der Server die Abfrage ab, statt irgendetwas zurückzugeben.
Resolver sind die Funktionen, die für jedes Feld die Daten beschaffen – aus einer Datenbank, einem anderen Dienst oder einer bestehenden REST-API. Das ist ein wichtiger Punkt für Unternehmen: GraphQL ist keine Datenbank und ersetzt keine. Es ist eine Schicht, die vorhandene Quellen unter einem gemeinsamen Schema zusammenführt.
Queries lesen Daten, Mutations ändern sie, also legen etwas an, aktualisieren oder löschen es. Dazu kommen Subscriptions für Echtzeit-Updates, etwa wenn sich ein Lagerbestand ändert. Sie laufen meist über WebSockets oder Server-Sent Events und sind in vielen Projekten der aufwendigste Teil.
Wo GraphQL seine Stärken ausspielt
Die Stärken zeigen sich vor allem dort, wo viele unterschiedliche Clients auf dieselben Daten zugreifen.
Mehrere Oberflächen, ein Backend: Angenommen, ein Händler betreibt einen Webshop, eine App und ein Kassensystem. Jede Oberfläche braucht andere Ausschnitte derselben Produktdaten. Mit GraphQL holt sich jede genau ihren Teil, ohne dass das Backend-Team für jede Ansicht einen eigenen Endpunkt bauen muss.
Verknüpfte Daten: Wo Daten stark miteinander verbunden sind – Kunden, Bestellungen, Artikel, Lieferungen oder in einem Redaktionssystem Artikel, Autoren, Rubriken und Medien –, lassen sich Beziehungen in einer Abfrage durchlaufen. Viele Headless-CMS bieten deshalb neben REST auch eine GraphQL-Schnittstelle an.
Typsicherheit im Frontend: Aus dem Schema lassen sich mit Werkzeugen wie GraphQL Code Generator automatisch TypeScript-Typen erzeugen. Ändert das Backend ein Feld, meldet der Compiler im Frontend den Fehler, bevor Nutzer ihn sehen. Clients wie Apollo Client, urql oder Relay ergänzen das um einen Zwischenspeicher im Browser und funktionieren mit React, Vue und anderen Frameworks.
Weiterentwicklung ohne Versionssprung: Neue Felder stören bestehende Abfragen nicht, weil jeder Client nur anfragt, was er kennt. Alte Felder lassen sich mit @deprecated als veraltet markieren und später entfernen. Ganz ohne Disziplin geht es trotzdem nicht: Wer ein Feld löscht oder seinen Typ ändert, bricht weiterhin Clients. Der Unterschied zu REST ist, dass Sie anhand der tatsächlichen Abfragen messen können, welches Feld noch genutzt wird.
Was GraphQL schwieriger macht
Die Flexibilität für den Client verlagert Arbeit auf den Server. Das wird in Einführungstexten gern unterschlagen.
Caching: REST profitiert vom HTTP-Caching. Eine GET-Anfrage an /produkte/42 kann ein Browser, ein Proxy oder ein CDN zwischenspeichern. GraphQL-Abfragen laufen dagegen häufig per POST an eine einzige Adresse, was diese Mechanismen aushebelt. Abhilfe schaffen sogenannte Persisted Queries, bei denen der Client nur noch eine Kennung für eine vorher registrierte Abfrage schickt, sowie Caches auf Ebene einzelner Objekte. Das funktioniert, ist aber zusätzlicher Aufwand.
Das N+1-Problem: Fragt ein Client 50 Bestellungen samt Kunde ab, ruft ein naiv geschriebener Resolver die Datenbank einmal für die Liste und 50-mal für die Kunden auf. Gängige Gegenmittel sind Batching-Werkzeuge wie DataLoader, die Einzelanfragen bündeln. Wie das konkret aussieht, beschreibt unser Infothek-Artikel zu N+1-Problem und Missbrauchsschutz bei GraphQL-APIs.
Sicherheit und Last: Weil Clients Abfragen frei formulieren, kann eine einzige, tief verschachtelte Abfrage den Server stark belasten – versehentlich oder absichtlich. Öffentliche GraphQL-APIs brauchen daher Grenzen für Abfragetiefe und Komplexität, Zeitlimits und eine Rechteprüfung auf Feldebene statt nur auf Endpunktebene. Die Introspection, mit der Werkzeuge das Schema abfragen, wird in Produktion oft eingeschränkt.
Fehlerbehandlung und Monitoring: Eine GraphQL-Antwort kommt häufig mit HTTP-Status 200, auch wenn Teile der Abfrage fehlgeschlagen sind; die Fehler stehen in einem eigenen Feld der Antwort. Standard-Monitoring, das auf Statuscodes schaut, sieht davon nichts. Auch Dateiuploads sind in GraphQL nicht vorgesehen und werden meist über separate Wege gelöst.
Wofür REST weiterhin die bessere Wahl ist
REST bleibt in vielen Fällen die einfachere und robustere Lösung:
- Öffentliche APIs mit vielen unbekannten Nutzern, etwa für Partner oder Behörden, profitieren von klaren Endpunkten, HTTP-Caching und der breiten Werkzeugunterstützung rund um die OpenAPI-Spezifikation.
- Einfache Datenmodelle, bei denen eine Oberfläche meist ganze Ressourcen braucht, gewinnen durch GraphQL wenig.
- Kommunikation zwischen Diensten im Backend läuft oft über REST, Nachrichtenwarteschlangen oder gRPC, weil dort keine flexiblen Abfragen gefragt sind.
- Dateien, Webhooks und Streaming passen natürlicher zu HTTP-Endpunkten.
In der Praxis findet man häufig beide: REST zwischen den Diensten im Backend und eine GraphQL-Schicht als einheitlicher Zugang für Web und App. Große Plattformen haben sich unterschiedlich entschieden. GitHub bietet seit 2016 neben seiner REST-API eine GraphQL-API an, beide werden weiter gepflegt. Shopify dagegen hat seine REST-Admin-API im Oktober 2024 zum Altbestand erklärt; neue öffentliche Apps müssen seit April 2025 ausschließlich die GraphQL-Admin-API nutzen.
Wie sich GraphQL seit 2021 entwickelt hat
Als dieser Beitrag 2021 zum ersten Mal erschien, war GraphQL vor allem ein Frontend-Thema. Seitdem hat sich das Bild verschoben. Die Spezifikation wird von der GraphQL Working Group weiterentwickelt, unterstützt von der GraphQL Foundation unter dem Dach der Linux Foundation. Mit Federation lassen sich mehrere GraphQL-Dienste verschiedener Teams zu einem gemeinsamen Schema zusammensetzen; dafür gibt es inzwischen Bestrebungen zu einem herstellerunabhängigen Standard.
Gleichzeitig ist der Hype abgeklungen. Für Anwendungen, bei denen Frontend und Backend in TypeScript im selben Repository liegen, wählen viele Teams leichtere Wege wie tRPC oder die Server-Funktionen moderner Frameworks wie Next.js, die Typsicherheit ohne eigenes Schema bieten. Und mit KI-Assistenten, die Schnittstellen aufrufen, gewinnt eine gut dokumentierte, maschinenlesbare Beschreibung an Bedeutung – das gilt für ein GraphQL-Schema ebenso wie für eine OpenAPI-Datei.
Was das für Ihr Team bedeutet
Unsere Einschätzung: GraphQL lohnt sich vor allem, wenn mehrere Oberflächen auf stark verknüpfte Daten zugreifen und das Frontend-Team schnell und unabhängig vom Backend arbeiten soll. Typische Kandidaten sind Webshops mit App, Kundenportale und Plattformen mit Headless-CMS. Überschätzt wird GraphQL als pauschaler Performance-Gewinn: Weniger Daten im Netz bedeuten nicht automatisch schnellere Seiten, wenn auf dem Server ineffiziente Resolver laufen.
Für ein kleines Team mit einer Webanwendung und einem klaren Datenmodell ist eine gut gestaltete REST-API meist der kürzere Weg. Wer GraphQL einführt, sollte von Anfang an Zeit für Caching, Abfragegrenzen, Rechteprüfung und Monitoring einplanen.
Eine sinnvolle Reihenfolge für die Entscheidung:
- Welche Clients greifen auf die Daten zu, und wie unterschiedlich sind ihre Bedürfnisse?
- Wie stark sind die Daten verknüpft?
- Ist die API öffentlich oder intern?
- Hat das Team Erfahrung mit dem Betrieb, nicht nur mit dem Schreiben von Abfragen?
Wenn Sie vor dieser Entscheidung stehen oder eine bestehende Schnittstelle modernisieren möchten, finden Sie auf unseren Seiten zu GraphQL-Beratung und -Seminaren und zu RESTful APIs die passenden Angebote. Die Umsetzung übernehmen wir im Rahmen von API-Integration und Backend-Entwicklung.
Häufige Fragen zu GraphQL und REST
Ist GraphQL schneller als REST?
Nicht grundsätzlich. GraphQL spart Anfragen und Datenvolumen, was vor allem bei mobilen Verbindungen hilft. Ob eine Seite schneller lädt, hängt aber davon ab, wie effizient die Resolver auf dem Server arbeiten und wie gut das Caching gelöst ist. Eine REST-API mit CDN-Cache kann schneller antworten als eine schlecht optimierte GraphQL-API.
Kann GraphQL auf einer bestehenden REST-API aufsetzen?
Ja, das ist ein häufiger Einstieg. Die Resolver rufen dann die vorhandenen REST-Endpunkte auf und fassen die Ergebnisse zusammen. So lässt sich GraphQL für ein neues Frontend testen, ohne das Backend umzubauen. Langfristig sollte man prüfen, ob die zusätzliche Schicht die Latenz erhöht.
Setzt GraphQL eine bestimmte Datenbank voraus?
Nein. GraphQL ist unabhängig von der Datenhaltung. Die Resolver können auf relationale Datenbanken, Dokumentenspeicher, Suchindizes oder externe Dienste zugreifen, auch auf mehrere gleichzeitig.
Wie aufwendig ist der Einstieg?
Die Abfragesprache ist schnell gelernt, wer JSON kennt, liest GraphQL-Abfragen nach kurzer Zeit. Der eigentliche Lernaufwand liegt beim Schemadesign und im Betrieb: Caching, Abfragegrenzen, Rechte und Monitoring erfordern Erfahrung, die sich ein Team erst aufbauen muss.
Kategorien
Schlagworte