GraphQL in Production: Wann es REST wirklich schlägt (und wann es mehr Probleme schafft)

#GraphQL Anwendungsfälle
Sandor Farkas - Founder & Lead Developer at Wolf-Tech

Sandor Farkas

Gründer & Lead Developer

Experte für Softwareentwicklung und Legacy-Code-Optimierung

Die meisten Teams, die GraphQL Anwendungsfälle bewerten, stellen die falsche Frage. Die Frage ist nicht "ist GraphQL besser als REST?", sondern "hat mein Produkt die spezifischen Datenzugriffsmuster, für die GraphQL gebaut wurde?". GraphQL wird eingeführt, weil ein Frontend-Team einen Konferenz-Talk gesehen hat, und zwei Jahre später aufgegeben, wenn die operative Rechnung fällig wird. Es wird genauso von Backend-Teams abgetan, die nie die Client-Vielfalt hatten, in der es glänzt.

Nachdem wir APIs auf beiden Modellen für B2B-SaaS-Produkte auditiert und gebaut haben, sehen wir immer wieder dasselbe Muster: Die Entscheidung gelingt oder scheitert am Fit, nicht an der Technologie selbst. Dieser Beitrag zeigt die vier Production-Szenarien, in denen GraphQL wirklich gewinnt, die vier, in denen es mehr Probleme schafft als löst, und die operative Arbeit, die du so oder so einplanen musst.

Vier GraphQL Anwendungsfälle, in denen es REST schlägt

1. Client-getriebene Datenanforderungen über Mobile und Web

Der klassische GraphQL-Gewinn: ein Produkt, mehrere Clients mit unterschiedlichen Datenbedürfnissen. Dein Web-Dashboard rendert eine Kundendetailseite mit 40 Feldern, Aktivitätshistorie und zugehörigen Rechnungen. Deine Mobile-App zeigt denselben Kunden als Karte mit 6 Feldern. Mit REST over-fetchst du entweder auf Mobile (verschwendet Bandbreite und Akku), baust separate Endpoints pro Client (verdoppelt die Wartung) oder erfindest eine Ad-hoc-Konvention wie ?fields=, die GraphQL langsam ohne dessen Tooling nachbaut.

Mit GraphQL deklariert jeder Client genau, was er braucht. Das Mobile-Team liefert eine schlankere Query ohne Backend-Ticket aus. Das ist keine hypothetische Bequemlichkeit: Auf getakteten Mobilverbindungen sind Response-Payloads, die von 80 KB auf 6 KB fallen, eine messbare UX-Verbesserung.

Der Test: Hast du mindestens zwei Clients, deren Datenanforderungen für dieselben Ressourcen deutlich auseinandergehen und sich unabhängig voneinander ändern? Wenn ja, verdient sich GraphQL seinen Platz.

2. Mehrere Services aggregieren, ohne für jeden Client ein BFF

Wenn deine Daten in mehreren Backend-Services liegen, braucht jede Client-Ansicht irgendwo Aggregation. Die REST-Antwort ist eine Backend-for-Frontend-Schicht (BFF), und BFFs vermehren sich: eins für Web, eins für Mobile, eins für das Partnerportal. Jedes ist eine Codebasis, die jemand wartet.

Ein föderiertes GraphQL-Gateway ersetzt diese Wucherung durch eine einzige Kompositionsschicht. Jeder Service besitzt sein Subgraph-Schema; das Gateway fügt sie zu einem Graphen zusammen. Clients fragen den Graphen ab, das Gateway löst über die Services hinweg auf. Du wartest eine Aggregationsschicht statt N, und das Schema wirkt als typisierter Vertrag zwischen Teams.

Das zahlt sich erst ab einer Schwelle aus: Mit zwei Services und einem Client ist ein BFF einfacher. Mit vier Services und drei Clients gewinnt meist das Gateway.

3. API-Produkte, bei denen externe Entwickler Flexibilität brauchen

Wenn deine API das Produkt ist, kannst du nicht vorhersagen, was Konsumenten bauen. Shopify und GitHub haben ihre Partner-APIs genau deshalb auf GraphQL umgestellt: Tausende Integratoren brauchen jeweils einen anderen Ausschnitt der Daten, und kein endliches Set an REST-Endpoints deckt sie alle ab.

GraphQL gibt externen Entwicklern Self-Service-Flexibilität, und das introspektierbare Schema ist zugleich immer aktuelle Dokumentation. Der Trade-off: Du musst von Tag eins in Query-Cost-Limiting investieren, weil du jetzt Queries ausführst, die du nicht geschrieben hast. Diese Investition behandeln wir unten, und für ein API-Produkt lohnt sie sich.

4. Schnelle Frontend-Iteration ohne Endpoint-Flaschenhals

In Produktphasen mit viel UI-Experimenten erzeugt REST eine Warteschlange: Jede neue Ansicht, die eine neue Datenform braucht, wartet auf einen Backend-Endpoint. Wenn das Frontend-Team wöchentlich iteriert und das Backend-Team in Zwei-Wochen-Sprints plant, wird diese Warteschlange zum Lieferengpass.

Mit einem einigermassen vollständigen Graphen komponieren Frontend-Entwickler neue Queries gegen bestehende Typen ohne Backend-Änderungen. Teams, die Cycle Time messen, stellen oft fest, dass GraphQL genau hier seine Komplexität bezahlt: nicht in Laufzeit-Performance, sondern in eingespartem Koordinationsaufwand.

Vier Szenarien, in denen GraphQL mehr Probleme schafft

1. Einfaches CRUD mit stabilen Schemas

Wenn deine Anwendung Formulare über Daten ist, mit einem einzigen Web-Client und Ressourcenformen, die sauber auf Screens abbilden, fügt GraphQL eine Resolver-Schicht, ein Schema, Client-Bibliotheken und Caching-Komplexität hinzu, um ein Problem zu lösen, das du nicht hast. REST mit gut gestalteten Ressourcen, oder sogar servergerenderte Seiten, liefert schneller und ist leichter zu debuggen. Die Mehrheit interner Tools und früher B2B-Produkte fällt in diese Kategorie. GraphQL hier einzuführen ist Resume-driven Architecture.

2. Performance-kritische Pfade mit unvorhersehbaren Query-Kosten

Ein REST-Endpoint hat ein bekanntes Kostenprofil: Du kannst ihn profilen, cachen und ein SLO darauf setzen. Ein GraphQL-Endpoint führt beliebige Queries aus, sein Kostenprofil ist also eine Verteilung mit langem Schwanz. Eine tief verschachtelte Query eines gutmeinenden Clients kann Hunderte Datenbank-Roundtrips erzeugen.

Für heisse Pfade mit strengen Latenzbudgets (Checkout, Search-as-you-type, Echtzeit-Dashboards) ist diese Unvorhersehbarkeit ein Risiko. Teams, die GraphQL für allgemeine Produktdaten behalten, bauen oft dedizierte REST- oder RPC-Endpoints für ihre performancekritischen Pfade. Das ist ein vernünftiger Hybrid, aber auch das Eingeständnis, dass der Graph diese Workloads nicht tragen konnte.

3. Teams ohne Tooling-Budget für Production-Härtung

Eine produktive GraphQL-API braucht Persisted Queries (damit Clients nur vorregistrierte Operationen ausführen können), Limits für Query-Tiefe und -Komplexität, Tracing auf Resolver-Ebene und Autorisierung auf Feldebene. Nichts davon ist optional; wer es weglässt, ist offen für triviale Denial-of-Service-Angriffe über verschachtelte Queries und für Autorisierungsbugs, die sich in Resolvern verstecken.

Das sind grob zwei bis vier Wochen Engineering-Investition vorab, plus laufende Ownership. Eine REST-API bekommt einen Grossteil der äquivalenten Härtung aus langweiliger, ausgereifter Middleware. Wenn dein Team diese Arbeit jetzt nicht finanzieren kann, wählst du nicht zwischen GraphQL und REST; du wählst zwischen REST und einem unsicheren GraphQL-Deployment.

4. Öffentliche APIs, bei denen Schema-Evolution Integratoren nicht brechen darf

REST-Versionierung ist grob, aber ehrlich: /v2/ signalisiert einen Breaking Change und lässt /v1/-Konsumenten weiterarbeiten. GraphQLs offizielle Position ist ein einziges versionsloses, evolvierendes Schema mit @deprecated-Feldern und späterer Entfernung. Das funktioniert, wenn du Feldnutzung beobachten und Konsumenten sanft weiterbewegen kannst, was für interne Clients und gemanagte Partner realistisch ist.

Für eine wirklich öffentliche API mit Tausenden unbekannten Integratoren ist eine Entfernung ein Breaking Change, egal wie lang das Deprecation-Fenster ist, und du kannst keine Leute anschreiben, die du nicht kennst. Öffentliche GraphQL-APIs sammeln deprecated Felder tendenziell endlos an, und das Schema wird zum Museum. Wenn deine Integratoren anonym und langlebig sind, ist RESTs explizite Versionierung der besser handhabbare Vertrag.

Das N+1-Problem: GraphQLs typischster Fehlermodus

Das N+1-Problem verdient einen eigenen Abschnitt, weil es die häufigste Ursache für "wir haben GraphQL eingeführt und unsere Datenbank ist umgefallen" ist.

Eine Query fordert 50 Kunden und die Rechnungen jedes Kunden an. Ein naiver Resolver holt die Kunden in einer Query und führt dann eine Rechnungs-Query pro Kunde aus: 51 Roundtrips. Verschachtle eine Ebene tiefer und du multiplizierst erneut. Nichts in GraphQL verhindert das standardmässig; das Ausführungsmodell lädt praktisch dazu ein, weil jeder Resolver isoliert läuft, ohne von seinen Geschwistern zu wissen.

Zwei ausgereifte Verteidigungen existieren:

  • DataLoader (Batching und Caching): Resolver fragen nicht direkt ab; sie reihen Keys in einen Loader ein, der alle Anfragen desselben Execution-Ticks zu einer WHERE id IN (...)-Query bündelt. Das ist das Standardmuster im JavaScript-Ökosystem und hat Ports für die meisten Sprachen. Es funktioniert, aber jede Relation braucht einen Loader, und einen zu vergessen führt N+1 stillschweigend wieder ein.
  • Der Ansatz von API Platform (Symfony/PHP): Statt Batching pro Feld löst API Platform GraphQL-Queries über dieselben Doctrine-gestützten Data Provider auf wie seine REST-Operationen, sodass Collection-Fetching und Eager-Loading-Konfiguration für beide gelten. Pagination ist auf Collections standardmässig erzwungen, was den Wirkungsradius verschachtelter Queries begrenzt. Du musst Eager Loading weiterhin bewusst konfigurieren, aber das Framework drängt dich zu mengenbasiertem Fetching statt zu Resolvern pro Item.

Welchen Stack du auch nutzt: Füge vor dem Launch Tracing auf Resolver-Ebene hinzu. N+1-Regressionen melden sich nicht im Code Review; sie zeigen sich als Datenbanklast, die mit der Response-Grösse wächst, und Tracing ist der Weg, sie zu fangen, bevor deine Nutzer es tun.

Eine Entscheidungscheckliste

Bewerte deine Situation ehrlich:

  • Zwei oder mehr Clients mit auseinanderlaufenden, unabhängig veränderlichen Datenbedürfnissen? Punkte für GraphQL.
  • Drei oder mehr Backend-Services, die Aggregation für mehrere Clients brauchen? Punkte für GraphQL.
  • Externe Entwickler, die unvorhersehbare Integrationen auf einer gemanagten Plattform bauen? Punkte für GraphQL.
  • Frontend-Iteration blockiert durch Backend-Endpoint-Lieferung? Punkte für GraphQL.
  • Ein Client, stabiles CRUD? REST gewinnt.
  • Strenge Latenz-SLOs auf heissen Pfaden? Dort gewinnt REST, egal was du sonst tust.
  • Kein Budget für Persisted Queries, Komplexitätslimits und Tracing? REST gewinnt per Default.
  • Anonyme öffentliche Integratoren, die versionierte Stabilität brauchen? REST gewinnt.

Wenn GraphQL deine Scorecard gewinnt, plane die Härtungsarbeit als Teil der Einführung ein, nicht als Fast-Follow. Wenn REST gewinnt, widersteh dem Reiz der Neuheit; eine gut gestaltete REST-API mit konsistenten Konventionen bleibt auch 2026 eine exzellente Architektur.

Die Wahl zwischen diesen Modellen ist ein Beispiel für die breiteren Stack-Entscheidungen, bei denen wir Teams in unseren Tech-Stack-Strategie-Engagements helfen. Und wenn du eine GraphQL-API mit mysteriösen Performance-Problemen geerbt hast, findet ein Audit über unser Code Quality Consulting das fehlende Batching meist innerhalb von Tagen. Für Teams, die neue APIs von Grund auf bauen, deckt unsere Webanwendungsentwicklung beide Modelle in Production ab.

Unsicher, auf welcher Seite der Checkliste dein Produkt landet? Schreib uns an hello@wolf-tech.io oder melde dich über wolf-tech.io auf unserer Kontaktseite, und wir sprechen deine konkreten Datenzugriffsmuster durch, bevor du dich in eine Richtung festlegst.