REST oder GraphQL? Eine Architekturentscheidung

Cyber-Panda als Psychologe zwischen zwei API-Schaltern

Einleitung

Du baust eine neue Schnittstelle. Mobile Apps, Web-Frontend, ein Drittsystem — alle brauchen Daten. Du stehst vor der Wahl: REST oder GraphQL? Beides funktioniert. Beides ist etabliert. Aber die Entscheidung beeinflusst, wie sich dein Team in den nächsten zwei Jahren bewegen wird.

Ich habe beide in Production laufen. Hier ist meine Entscheidungslogik.

Kontext

Es geht nicht um „welches ist besser”. Es geht um Fit für den Use Case.

REST (Representational State Transfer) ist ein Architekturstil: Ressourcen, Endpunkte, HTTP-Verben. GraphQL ist eine Query-Sprache plus Runtime: ein Endpunkt, Clients definieren, was sie brauchen.

Constraints in meinem Szenario:

  • Mobile Clients mit schwankender Netzqualität
  • Wachsendes Frontend-Team, das Features schnell ausliefern muss
  • Backend-Team, das stabile Schnittstellen priorisiert
  • Legacy-Datenbank, die nicht ohne Weiteres umgestellt werden kann

Non-Goals:

  • Universelle „beste” Lösung
  • Migration bestehender Systeme um jeden Preis
  • Hype folgen

Option A: REST — Das Bekannte

# GET /api/v1/users/42
# Response: volles User-Objekt + Adressen + Bestellungen
{
  "id": 42,
  "name": "Kai",
  "email": "...",
  "addresses": [...],
  "orders": [...]
}

Pros:

  • HTTP-Standard, Caching funktioniert out-of-the-box
  • Einfache Toolchain (curl, Browser, Swagger/OpenAPI)
  • Klare Trennung der Verantwortlichkeiten
  • Breite Akzeptanz im Team

Cons:

  • Over-fetching: Client bekommt 12 Felder, braucht 3
  • Under-fetching: Für eine View braucht er 4 Endpunkte
  • Versionierung wird schnell unübersichtlich (/v1, /v2, /v3)
  • Frontend-Team muss warten, bis Backend-Endpunkte existieren

Option B: GraphQL — Das Flexible

# POST /graphql
query {
  user(id: 42) {
    name
    email
    orders(limit: 5) {
      total
      status
    }
  }
}

Pros:

  • Client holt genau das, was er braucht
  • Ein Endpunkt für alle Anwendungsfälle
  • Self-documenting Schema (Introspection)
  • Frontend-Team arbeitet unabhängiger

Cons:

  • Caching ist komplexer (kein Standard-HTTP-Cache auf Query-Ebene)
  • Query-Komplexität kann die Datenbank belasten
  • Lernenkurve für Backend-Entwickler
  • Monitoring und Performance-Tracing gewöhnungsbedürftig

Entscheidung

GraphQL für neue Features, REST für bestehende Endpunkte.

Warum? Meine Mobile-Clients hatten wiederholt Performance-Probleme durch Over-fetching. Bei einer Bestellübersicht lud der Client 400 KB, brauchte aber nur 80 KB. Bei 3G war das spürbar.

GraphQL löst das. Der Client requestet genau die Felder, die die View rendert. Nichts mehr, nichts weniger.

Trade-offs, die ich eingehe:

  • Caching: Ich nutze stale-while-revalidate mit normalisierten Cache-Keys auf CDN-Ebene für häufige Queries. Nicht perfekt, aber gut genug.
  • Query-Kosten: Ich setze einen maxQueryDepth und ein Timeout. Tief geschachtelte Abfragen werden abgelehnt.
  • Backend-Komplexität: Das Team brauchte zwei Wochen Einarbeitung. Danach waren sie produktiver.

Ich habe REST nicht komplett abgeschafft. Public-API und Integrationen bleiben REST, weil dort Caching und Versionierung klare Vorteile haben.

Implementierung

Minimales Beispiel mit Node.js und Apollo Server:

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const typeDefs = `#graphql
  type User {
    id: ID!
    name: String!
    email: String!
    orders(limit: Int = 10): [Order!]!
  }

  type Order {
    id: ID!
    total: Float!
    status: String!
  }

  type Query {
    user(id: ID!): User
  }
`;

const resolvers = {
  Query: {
    user: (_, { id }) => database.users.find(id),
  },
};

const server = new ApolloServer({ typeDefs, resolvers });
const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });
console.log(`GraphQL bereit unter ${url}`);

Clients können jetzt flexibel kombinieren:

query {
  user(id: "42") {
    name
    orders(limit: 3) {
      total
    }
  }
}

Fazit

Die Entscheidung für GraphQL hat sich gelohnt — für den internen Client. Over-fetching ist weg, das Frontend-Team arbeitet schneller.

Aber: GraphQL ist kein Allheilmittel. Für öffentliche APIs, Webhooks oder Drittsysteme bleibe ich bei REST. Die Kombination funktioniert.

Offene Frage an dich: Wo siehst du die Grenzen von GraphQL? Hast du schlechte Erfahrungen mit komplexen N+1-Problemen gemacht? Schreib mir in den Kommentaren.


Siehe auch: