GraphQL vs REST in TypeScript: Was für Ihr Projekt wählen?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

GraphQL vs REST in TypeScript: Duell der Titanen oder Wahl nach Aufgabe?

\n\n

Wenn Sie in TypeScript schreiben, stellt sich die Frage nach der Backend-Architektur besonders dringend. Man möchte nicht nur, dass es "funktioniert", sondern dass Typen fliegen, Fehler zur Kompilierungszeit abgefangen werden und der Code vorhersagbar ist. Und hier steht der Entwickler vor der ewigen Wahl: das bewährte REST oder das moderne, flexible GraphQL? Beide Technologien harmonieren hervorragend mit TypeScript, aber jede diktiert ihren eigenen Entwicklungsstil.

\n\n

In diesem Artikel werden wir keine Allgemeinplätze wiederholen. Wir analysieren GraphQL vs REST in TypeScript an konkreten Beispielen, mit Code, Engpässen und Szenarien, in denen ein Ansatz den anderen übertrifft. Los geht's!

\n\n

REST: Ein alter Freund, der nicht enttäuscht

\n\n

REST (Representational State Transfer) ist ein Architekturstil, bei dem jede Ressource (Benutzer, Beitrag, Kommentar) ihre eigene URL hat. Sie greifen auf /api/users/1 zu und erhalten den Benutzer. Einfach und vorhersagbar. In TypeScript-Projekten wird REST oft mit Express, Fastify oder NestJS implementiert.

\n\n

Typisierung in REST mit TypeScript

\n

Der Hauptschmerz von REST ist die schwache Verbindung zwischen Backend und Frontend. Sie senden JSON, und das Frontend rätselt: "Was ist da angekommen?". TypeScript rettet durch gemeinsame Typen oder OpenAPI (Swagger).

\n\n

Beispiel: Backend mit Express und TypeScript

\n\n
import express, { Request, Response } from 'express';\n\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nconst app = express();\napp.get('/api/users/:id', (req: Request, res: Response) => {\n  const user: User = { id: +req.params.id, name: 'Alice', email: 'alice@example.com' };\n  res.json(user);\n});\n
\n\n

Frontend (fetch):

\n\n
interface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nasync function getUser(id: number): Promise<User> {\n  const res = await fetch(`/api/users/${id}`);\n  return res.json() as Promise<User>;\n}\n
\n\n

Problem: Wenn das Backend die User-Struktur ändert, erfährt das Frontend davon erst zur Laufzeit. Die Typen im Frontend sind nur eine Kopie. Lösung: Generierung von Typen aus der OpenAPI-Spezifikation.

\n\n

Vorteile von REST in TypeScript

\n
    \n
  • Einfaches Caching: HTTP-Cache (CDN, Browser) funktioniert sofort.
  • \n
  • Klare Struktur: URL = Ressource, Methoden = Aktionen (GET, POST, PUT, DELETE).
  • \n
  • Breite Unterstützung: Jeder Client (Browser, curl, Postman) versteht REST.
  • \n
  • Niedrige Einstiegshürde: Selbst ein Junior versteht es in einer Stunde.
  • \n
\n\n

Nachteile von REST

\n
    \n
  • Over-fetching und Under-fetching: Sie ziehen entweder unnötige Felder oder machen mehrere Anfragen.
  • \n
  • Starre Struktur: Um einen Benutzer + seine Beiträge zu erhalten, braucht man zwei Anfragen oder Workarounds (expand-Feld).
  • \n
  • Schwache Typisierung: Ohne OpenAPI sind die Typen auf dem Client nur ein "Ehrenwort".
  • \n
\n\n

GraphQL: Flexibilität und Kontrolle

\n\n

GraphQL ist eine Abfragesprache, die dem Client das Recht gibt, selbst zu entscheiden, welche Daten er erhält. Ein Endpunkt (/graphql), eine Anfrage – und Sie erhalten genau das, was Sie bestellt haben. TypeScript und GraphQL sind ein ideales Paar: Typen werden automatisch aus dem Schema generiert.

\n\n

Typisierung in GraphQL mit TypeScript

\n

Zuerst wird das Schema (SDL) geschrieben:

\n\n
type User {\n  id: ID!\n  name: String!\n  email: String!\n  posts: [Post!]!\n}\n\ntype Post {\n  id: ID!\n  title: String!\n  content: String!\n}\n\ntype Query {\n  user(id: ID!): User\n}\n
\n\n

Dann werden die Typen generiert (über graphql-codegen):

\n\n
// generated.ts\nexport type User = {\n  __typename?: 'User';\n  id: string;\n  name: string;\n  email: string;\n  posts: Array<Post>;\n};\n\nexport type Post = {\n  __typename?: 'Post';\n  id: string;\n  title: string;\n  content: string;\n};\n

                
                

Blogs

Buchempfehlungen