Back

Typsichere API-Clients mit OpenAPI und TypeScript erstellen

Typsichere API-Clients mit OpenAPI und TypeScript erstellen

Jeder Frontend-Entwickler kennt das: Man ruft Daten von einer API ab, greift auf ein Feld zu, das existieren sollte, und erhält zur Laufzeit undefined. TypeScript sollte das eigentlich verhindern. Das Problem ist, dass response.json() den Typ any zurückgibt, sodass der Compiler nichts überprüfen kann. Dieser Leitfaden zeigt Ihnen, wie Sie das richtig lösen – indem Sie Typen direkt aus Ihrer OpenAPI-Spezifikation generieren und diese verwenden, um typsichere REST-Clients in TypeScript zu erstellen.

Wichtigste Erkenntnisse

  • Manuell geschriebene TypeScript-Interfaces weichen von Ihrer tatsächlichen API ab und erzeugen ein falsches Sicherheitsgefühl, das zu Laufzeitfehlern führt.
  • OpenAPI-Code-Generierung erzeugt Typen direkt aus Ihrer API-Spezifikation und hält Frontend und Backend synchron.
  • Verwenden Sie openapi-typescript mit openapi-fetch für ein schlankes, fetch-basiertes Setup oder Orval für generierte TanStack-Query-Hooks und vollständige Client-SDKs.
  • Automatisieren Sie die Typ-Generierung in CI oder Ihren Build-Scripts, damit Typen niemals veralten.
  • Kombinieren Sie generierte Typen mit einem Runtime-Validator wie Zod für kritische Endpunkte, bei denen Compile-Time-Sicherheit allein nicht ausreicht.

Warum manuelle Typisierung scheitert

Die naive Lösung besteht darin, Interfaces von Hand zu schreiben:

// ❌ Kompiliert einwandfrei, aber TypeScript vertraut Ihnen einfach
const data = (await response.json()) as User

Das gibt Ihnen Autovervollständigung, aber es wird zur Lüge, sobald sich das Backend ändert. Ihre Typen weichen von der Realität ab, und Sie sind wieder bei Laufzeit-Überraschungen.

Der bessere Ansatz: Generieren Sie Typen aus der einzigen Wahrheitsquelle – Ihrer OpenAPI-Spezifikation.

Der OpenAPI-TypeScript-Code-Generierungs-Workflow

Der typische Workflow sieht folgendermaßen aus:

  1. Beginnen Sie mit einer OpenAPI-Spezifikation (YAML oder JSON, gehostet oder lokal)
  2. Führen Sie einen Generator aus, um TypeScript-Typen oder einen vollständigen Client zu erzeugen
  3. Importieren Sie diese Typen in Ihren Anwendungscode

Dies hält Ihr Frontend automatisch mit dem Backend synchron. Wenn sich die Spezifikation ändert, generieren Sie neu, und TypeScript zeigt Ihnen genau, was kaputt gegangen ist.

Wahl Ihres Ansatzes: Nur Typen vs. vollständiges Client-SDK

Es gibt zwei Hauptstrategien für die OpenAPI-TypeScript-Code-Generierung, und die richtige Wahl hängt von Ihrem Projekt ab.

AnsatzToolsAm besten geeignet für
Typen generieren, eigenen Fetch verwendenopenapi-typescript + openapi-fetchSchlanke, fetch-basierte Projekte
Vollständiges Client-SDK generierenOrval, OpenAPI GeneratorTeams, die fertige Hooks und Clients wünschen

Reine Typ-Generierung hält Ihr Bundle klein und lässt Sie die HTTP-Schicht kontrollieren. Vollständige SDK-Generierung spart Verkabelungszeit, fügt aber mehr generierten Code hinzu, den Sie pflegen müssen.

OpenAPI 3.0 vs. 3.1: Die meisten Tools unterstützen OpenAPI 3.0 gut. Die Unterstützung für OpenAPI 3.1 variiert – prüfen Sie die Dokumentation Ihres Generators, bevor Sie vollständige Kompatibilität annehmen.

Ansatz 1: openapi-typescript mit openapi-fetch

Dies ist der Weg mit minimaler Runtime. Generieren Sie Typen aus Ihrer Spezifikation und verwenden Sie dann openapi-fetch als schlanken, vollständig typisierten Wrapper um die native Fetch-API.

npx openapi-typescript ./openapi.yaml -o ./src/api/types.ts
npm install openapi-fetch
import createClient from "openapi-fetch"
import type { paths } from "./api/types"

const client = createClient<paths>({ baseUrl: "https://api.example.com" })

// Pfad, Parameter und Response werden alle typ-geprüft
const { data, error } = await client.GET("/users/{id}", {
  params: { path: { id: 123 } },
})

// TypeScript weiß genau, wie `data` aussieht
console.log(data?.email)

Tippfehler in Pfaden, falsche Parametertypen und nicht übereinstimmende Response-Strukturen werden alle zu Compile-Fehlern. Minimaler Runtime-Overhead und nur eine kleine Runtime-Abhängigkeit (openapi-fetch).

Ansatz 2: Orval für vollständige Client-Generierung

Orval generiert typisierte API-Funktionen und – entscheidend – kann TanStack Query-Hooks direkt aus Ihrer Spezifikation ausgeben. Dies ist nützlich, wenn Sie möchten, dass die Datenabruf-Logik für Sie übernommen wird.

npm install orval --save-dev

Konfigurieren Sie orval.config.ts, um auf Ihre Spezifikation zu verweisen und einen Output-Modus zu wählen (fetch, axios oder react-query). Orval generiert dann Funktionen wie useGetUsers() mit eingebauter vollständiger Typsicherheit.

Dieser Ansatz fügt mehr generierten Code hinzu, reduziert aber bei größeren APIs erheblich den Boilerplate-Code.

Typen synchron halten

Der eigentliche Wert der OpenAPI-TypeScript-Client-Generierung gilt nur, wenn Sie konsistent neu generieren. Fügen Sie den Generierungsschritt zu Ihrem Entwicklungs-Workflow hinzu:

{
  "scripts": {
    "generate:api": "openapi-typescript ./openapi.yaml -o ./src/api/types.ts"
  }
}

Führen Sie es in CI aus oder überwachen Sie Spezifikationsänderungen lokal. Einige Teams committen die generierte Datei; andere generieren bei jedem Build neu. Beides funktioniert – machen Sie es nur automatisch.

Was Sie noch handhaben müssen

Generierte Typen bieten normalerweise nur Compile-Time-Sicherheit. Runtime-Validierung erfordert zusätzliche Tools wie Zod oder Generator-Plugins. Kombinieren Sie für kritische Endpunkte Ihre generierten Typen mit Zod, um Responses zur Laufzeit zu validieren und Backend-Bugs abzufangen, bevor sie Ihre UI erreichen.

Fazit

OpenAPI-TypeScript-Code-Generierung ist eine der wirkungsvollsten Verbesserungen, die Sie an einer Frontend-Codebase vornehmen können. Wählen Sie openapi-typescript mit openapi-fetch für ein schlankes Setup oder Orval, wenn Sie generierte Query-Hooks möchten. In jedem Fall hören Sie auf, Typen von Hand zu schreiben, hören auf, Response-Strukturen zu erraten, und lassen den Compiler die Arbeit machen, für die er entwickelt wurde.

Häufig gestellte Fragen

Ja. openapi-typescript unterstützt sowohl OpenAPI 3.0- als auch 3.1-Spezifikationen, obwohl einige Schema-Features möglicherweise Tests mit Ihrem spezifischen Generator und Ihrer Spezifikation erfordern. Überprüfen Sie immer die generierte Ausgabe nach dem Upgrade Ihrer Spezifikationsversion.

Absolut. Generierte Typen geben Ihnen Compile-Time-Sicherheit, während Zod Daten zur Laufzeit validiert. Sie können Zod-Schemas definieren, die Ihre generierten Typen spiegeln, und API-Responses durch sie parsen. Dies fängt Fälle ab, in denen das Backend unerwartete Daten zurückgibt, die der Compiler nicht erkennen kann.

Beide Ansätze funktionieren. Das Committen generierter Dateien macht Builds schneller und ermöglicht es Ihnen, Typ-Änderungen in Pull Requests zu überprüfen. Die Neugenerierung bei jedem Build stellt sicher, dass Typen immer aktuell sind, fügt aber eine Build-Step-Abhängigkeit hinzu. Wählen Sie, was am besten zum Workflow und CI-Setup Ihres Teams passt.

Orval ist speziell für TypeScript entwickelt und gibt TanStack-Query-Hooks, Axios-Clients oder Fetch-Funktionen mit minimaler Konfiguration aus. OpenAPI Generator unterstützt viele Sprachen, erzeugt aber ausführlicheren TypeScript-Output. Für frontend-fokussierte Teams erfordert Orval typischerweise weniger Anpassung, um sauberen, idiomatischen Code zu erhalten.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay