Zum Hauptinhalt springen
Entwicklung Mobil

OpenAPI TypeScript: Erstellen von Typen, Clients und Validierung

Erklären Sie, wie die OpenAPI TypeScript-Generierung von Anfang bis Ende funktioniert. Erstellen Sie Typen, verbinden Sie Clients, validieren Sie bei Laufzeit und schicken Sie sicher von CI aus.

OpenAPI TypeScript: Generieren Sie Typen, Clients und Validierung

Sie können normalerweise den Moment erkennen, an dem ein API Pipeline der Mannschaft beginnt, zu lügen. Ein Schema ändert sich, die generierten Typen aktualisieren sich ohne Beschwerden, der PR geht grün, und dann liest jemand in der Frontend immer noch die alte Antwortform, weil der Wrapper die Fehler abgeschirmt hat. Das ist das OpenAPI TypeScript Problem, nicht, ob ein Generator Interfaces ausstoßen kann.

Die nützlichere Frage ist schwieriger. Was ist der Vertrag, den Sie zwischen Schema, Transport und Validierung wollen, und welche Teile sollten schnell in der Buildzeit scheitern, anstatt in der Laufzeit zu lecken? OpenAPI TypeScript Als Pipeline-Wahl werden die Vor- und Nachteile klarer, und die Tools stoppen, sich als ganze Lösung auszugeben.

Inhaltsverzeichnis

Why Generierte Typen Sind Nicht Das Gleiche Wie Ein Sicheres API

Eine Kollegin fusioniert einen PR, der eine optionale Antwortfeld hinzufügt. Die generierte Datei aktualisiert sich sauber, der Diff sieht langweilig aus und jeder geht weiter. Dann liest die Frontend-Implementierung weiterhin eine ältere Form durch eine handschriftliche Wrapper, die "vorübergehend" mit einem Cast umgewandelt wurde as any, und die Produktion beginnt, als ob der Vertrag nie geändert wurde.

Dass ist der Haken mit generierten Typen. TypeScript kann nur den code schützen, der die generierten Typen konsumiert, und nur, wenn die Transportlayer nicht den Vertrag wieder löscht. Die OpenAPI-Seite gibt dir ein Schema, nicht eine Garantie, dass jeder Aufrufer es respektiert. Die Diskussion um die Verständigung von API-Verbindungen ist hier hilfreich, weil sie die Konversation von einem einzelnen Werkzeug weg und hin zu den Verbindungen zwischen Systemen lenkt.

Wo die Fehler verborgen sind

Die meisten Bruchpunkte sind langweilig, nicht exotisch. Schema-Drift happens, wenn OpenAPI-Spezifikation und implementierte Dienst nicht mehr übereinstimmen. Teilweiser Abdeckungsgrad erscheint, wenn eine Spezifikation nur den glücklichen Weg modelliert, während die App auf ungedokumentierte Randfälle angewiesen ist. Manuelle Wrapper sind oft dort, wo sich die Typen schwächen, insbesondere, wenn jemand "schnell vorankommen" möchte und any oder eine lose Antwort cast verwendet.

Praktische Regel: wenn der Wrapper lügen kann, kann der Generator nicht helfen.

Es gibt auch einen Laufzeitunterschied. TypeScript-Typen verschwinden nach der Kompilierung, sodass sie nicht auf fehlerhaftes JSON reagieren können, das über das Netzwerk kommt. Das Netzwerk kümmert sich nicht darum, was Ihr Editor angenommen hat, und das ist der Grund, warum ein generierter Client nur eine Schicht in einer sicheren API Pipeline ist.

Die breitere operativen Frage ist die Sicherheit und die Vertragsdisziplin, nicht nur die Entwicklerkomfort. Wenn Sie eine strukturierte Sicht auf, wie API Verträge in einen größeren App-Lifecycle passen, ist diese interne Anleitung zu den API Sicherheitsstandards für die App-Store-Konformität API security standards for app store compliance Die reife Art, über

Die reife Art, darüber nachzudenken typescript OpenAPI Ist das. Es gibt Ihnen eine strenge Brücke von Schema zu Typen, die hervorragend ist, aber es überprüft keine Anfragen, erzwingt keine Ausführungszeit-Payload-Form oder stoppt einen schlampigen Wrapper, der alles untergräbt. Der Generator ist der leichte 20 Prozent. Der Rest ist die Pipeline-Design, und das ist, wo Teams entweder Vertrauen gewinnen oder falsche Zuversicht anhäufen.

typescript-Generierung aus einer OpenAPI-Spezifikation

Bild von https://openapi-ts.dev

Der leichte nützliche Setup ist normalerweise der, der realen Repo-Churn überlebt. Halten Sie die OpenAPI-Spezifikation im selben Repository, generieren Sie eine verpflichtete Typdatei und machen Sie den Drift in CI sichtbar, anstatt auf jemanden zu vertrauen, der sich an einen Refresh-Schritt erinnert. npx openapi-typescript ./openapi.yaml -o ./src/types/api.d.ts gibt Ihnen eine deterministische Ausgabedatei, die Rezensenten wie jede andere Quelländernder inspizieren können.

Die Flags, die tatsächlich zählen

Die -o Die Ausgabeflagge zählt, weil sie das generierte Artefakt explizit macht. --immutable ist nützlich, wenn Sie die generierten Typen dazu bringen möchten, die readonly-Intention im Ausgang zu bewahren, und --alphabetize hält Diffs stabil, wenn die Schemasortierung ohne semantische Bedeutung ändert. --enum zählt, wenn Ihr Team Vorzüge für Enums in der generierten Oberfläche bevorzugt anstatt von Unions.

Die Projekt-Dokumentation ist klar über den Umfang informiert, es ist ein Typ-Generator, kein Client- Runtime oder Anforderungs-Layer, und diese Einschränkung hilft, wenn Sie ein leichtgewichtiges, type-first Setup wollen. Sein Repository zeigt auch das Wartungsmodell hinter der Werkzeug, was Teil davon ist, warum Open-Source-Werkzeuge in der Produktion halten können, wenn die Dokumentation und Releases aktiv bleiben, wie in Der Fall für Open-Source-WartungEin nützlicher Beitrag zu dieser Haltung ist das Projekt GitHub-Repository und CLI-Dokumentation.

Dokumentation. Die Wire-Generierung in package.json so the command lives beside the rest of the build scripts, then run it whenever the spec changes. In CI, regenerate the file and fail if git diff zeigt einen Drift. Das wandelt Änderungen an Verträgen in sichtbares Überprüfungsarbeiten um, anstatt stillschweigende Laufzeitrisiken.

Das Schema-Seitige ist genauso wichtig wie die Befehlszeile. Das Projekt empfiehlt compilerOptions.noUncheckedIndexedAccess so additionalProperties become T | undefinedwas sicherere Indexierung an Aufrufstellen erzwingt. Es wird auch empfohlen, oneOf an sich anstatt mit zusätzlicher Komposition zu mischen, und die $defs am Wurzelort zu behalten, wenn die Platzierung zweideutig ist, weil fehlplatzierte Definitionen aus der generierten Ausgabe verschwinden können. Ein weiterer Detail spart Zeit später, openapi-typescript werden nie produziert, any, so fehlende Schema-Detail wird frühzeitig angezeigt anstatt unter permissiven Typen verborgen.

Halten Sie die Spezifikation explizit, oder der Generator wird die Zweideutigkeit treu wieder an Sie zurückgeben.

Der Workflow, der hält, ist einfach. Legen Sie die Spezifikation unter Versionskontrolle, regenerieren Sie bei der Build, committen Sie das generierte Datei, und lassen Sie den Typenprüfer vorher klagen, bevor jemand einen Mismatch miteinbezieht. Das gibt Ihnen eine stabile Vertragsgrenze für den Rest der Pipeline.

Wählen Sie zwischen reinen Typen, vollständigen Clients und keinem Codegenerierung

Muster Buildzeit Ausgabedateien Paketgewicht Beste Passform
Reine Typen mit einer dünnen Wrapper Schnell Wenig Niedrig Teams, die Kontrolle und eine kleine Laufzeitoberfläche wollen
Vollständige Client-Codegenerierung Langsamer Viele Höher Teams, die eine schnelle Übergabe und automatisierte Operationen wollen
Keine Codegenerierung für Anfragebauer Schnell Keine oder minimale Niedrig Einreihen-Apps, die eine manuell geschriebene Transportlogik bevorzugen

Die Wahl ist nicht wirklich "welches Werkzeug gewinnt". Es ist die Pipelineform, die zu Ihrem Repository, Ihrem Team und der Anzahl der Änderungen im API passt. In einer 2025-Benchmark um ein großes OpenAPI-Spezifikum von etwa 75.000 Zeilen, 2 MB und etwa 1.200 Operationen, openapi-typescript erzeugte Ausgabe in etwa 1,5 Sekunden im Durchschnitt, verglichen mit etwa 8,0 Sekunden für @hey-api/openapi-ts, 5,5 Sekunden für Orval, und 18,1 Sekunden für Kubb, wobei auch ein einzelnes Ausgabedatei gegenüber 16 für hey-api, 2,719 für Orval, und 3,877 für Kubb (Benchmark-Daten).

Reine Typen bevorzugen die Kontrolle

A pure-types setup pairs well with a handwritten request layer because you can keep the runtime tiny and the API surface boring. That matters in bundler-sensitive front ends and in apps where one team owns both the spec and the consumer. If you need a reminder that developer experience is not just syntax sugar, the developer experience angle ist einfacher zu beurteilen, wenn Ihr Client code kurz, offensichtlich und überprüfbar ist.

Vollklienten bevorzugen die Geschwindigkeit der Handover

openapi-generator, hey-api, Orval, und Kubb alle versuchen, mehr als Typen zu tun. Das kann hilfreich sein, wenn Sie Methoden für Anfragen, Modelle und Rohre gemeinsam generieren möchten, insbesondere bei einer großen Handover zwischen Backend- und Frontend-Teams. Der Preis ist offensichtlich im Benchmark oben, mehr generierte Dateien, mehr Laufzeitoberfläche und mehr Raum für Baufriction, wenn die Spezifikation wächst.

Keine Codegenerierung bevorzugt lokale Refaktoren

Typisierte Anforderungsbauern und fetch Wrapper funktionieren gut, wenn ein Codebase beide Enden der Form und die API Änderungen eng koordiniert sind. Der Nachteil ist die Aufrechterhaltungsdisciplin. Je mehr Teams und Repositories zwischen Produzent und Verbraucher sitzen, desto wahrscheinlicher driftet eine handgeschriebene Anforderungsschicht, es sei denn, Sie setzen aggressive Vertragsprüfungen ein.

Das Kernentscheidungspunkt ist nicht ideologisch. Wenn Ihr Bundle-Budget knapp ist, sind reine Typen attraktiv. Wenn Ihr Team maximalen Aufbauzeit gewünscht und die Ausgabe aufnehmen kann, reduzieren Vollklienten die Einrichtungszeit. Wenn Sie minimalen Bewegungsteil und die Vertragsnähe halten möchten, können no-codegen-Anforderungsbauern die richtige interne Handelsstrategie sein.

Ein Thin-Typed-Client um den Fetch- oder Axios-Service zu umschreiben

Ein Diagramm, das einen vom TypeScript generierten Wrapper-Prozess für Webanfragen zeigt, der mit definierten API-Typen arbeitet.

Außerhalb der Wrapper liegt der Generator und dort beginnt Ihre Anwendung code. Der Wrapper sollte eine Funktion pro Operation bereitstellen, parametrische und Abfrageobjekte akzeptieren und den Aufruf an die fetch oder eine injizierte axios Instanz ohne zu versuchen, clever zu sein. In der Regel bleibt diese Schicht in Produktionsumgebungen erhalten. 30–60 Zeilen weil die generierten Typen bereits den größten Teil der Form aufweisen.

Hier ist das mentale Modell, das funktioniert:

  • kann man sie nicht ohne eine so /users/{id} kann nicht ohne einen aufgerufen werden. id.
  • Antwortkörper bleiben getippt optional Filtern werden nicht in einen String-Brei verwandelt.
  • also kann man sie nicht ohne eine so kann die Verarbeitung von code auf die enge Form vertrauen, die sie erwartet.

Ein Wrapper wie dieser ist absichtlich langweilig. Er sollte keine Wiederholungen, Transformationen oder Auth-Politiken erfinden, wenn diese an anderer Stelle gehören. Er sollte die Anfrage von einem typisierten Betrieb in den Transportlayer verschieben und dann den typisierten Ergebnis zurückgeben.

Halte den Wrapper langweilig und abhängigkeitsarm, oder jede zukünftige Änderung des Codegenerators wird sich auf dein App auswirken.

Die häufige Fehlleistung besteht darin, Mismatches mit as any Wenn du Axios bevorzugst, ist das Muster gleich, nur die Transportimplementierung ändert sich. Wenn du einfache Browser-Seiten __CAPGO_KEEP_0__ bevorzugst, ist oft genug.

For teams that prefer Axios, the pattern is the same, only the transport implementation changes. For teams that want simpler browser-side code, fetch is often enough. The important part is that the request function accepts the generated path type and returns a typed response, not a loosely shaped object that gets massaged later.

Wenn Sie dies gut einsetzen. OpenAPI für TypeScript gives you a clean division of labor. Schema lives in the spec, transport lives in the wrapper, and the app sees typed operations instead of ad hoc request code.

Hinzufügen von Laufzeitvalidierung mit zod, ajv oder io-ts

Typsript-Typen verschwinden bei Laufzeit, und das Netzwerk kümmert sich nicht um die Zuversicht Ihres Editors. Deshalb ist die sichere Vorgehensweise nicht "Typen generieren und hoffen", sondern "Typen generieren, dann bei der Kante, wo unvertrauenswürdige Daten in die App eintreten, validieren". Das generierte Schema bleibt die Quelle der Wahrheit, und Validierungsbibliotheken wie zod, ajv, und io-ts handeln die Grenzwerte, die Zeittypen nicht kompilieren können.

Validieren, wo die Daten eintreten

Für React-Apps ist die Kante normalerweise direkt nachdem die Anfrage aufgelöst wurde und bevor der Payload in den Zustand eingeht. Für Server ist es, bevor der Payload in eine Datenbank geschrieben wird oder an eine Geschäftsregel weitergegeben wird. Die Regel ist einfach: Halten Sie die Validierung in der Nähe der Kante und streuen Sie keine manuellen Überprüfungen durch die Feature code.

A zod Die Form kann die Form der generierten Antwort widerspiegeln, ohne sie zu ersetzen:

import { z } from "zod";

const WeatherForecastSchema = z.object({
  date: z.string(),
  temperatureC: z.number(),
  summary: z.string().nullable(),
  temperatureF: z.number().optional(),
});

Das Beispiel überprüft die Felder, die das Schema als optional markiert, und hält die Laufzeitprüfung mit dem von dem Generator erzeugten Ergebnis im Einklang. ajv ein starkes Wahl, wenn Sie eine hohe Durchsatz-JSON-Schema-Validierung auf dem Server benötigen, während io-ts still passt Teams, die bereits dort leben fp-ts Kompositionsstil

The big mistake is validating too late. If the payload crosses into your app first, the type system has already been bypassed and the bug has a place to hide. A short guide on Einheitstests für JavaScript passt sich gut diesem Denkansatz an, da sowohl Einheitstests als auch Grenzwertvalidierung am besten funktionieren, wenn sie frühzeitig schlechte Annahmen erkennen.

Die saubere Schichtung ist vorhersehbar. OpenAPI TypeScript generiert den Vertrag, der Validator überprüft die Laufzeitdaten, und Ihre App code sieht nur Daten, die beide Schritte überstanden haben. Das ist ein viel besseres Grenzwert als das Vertrauen in eine statische Typisierung, um einen unvertrauenswürdigen Antwort zu überwachen.

Einbindung von Generation, Validierung und Vertragsprüfungen in CI

Bild aus https://github.com

Ein Pipeline, der anhält, verwandelt den Vertrag in eine Schranke, nicht in eine Empfehlung. Regenerate Typen, auf Drift scheitern, ausführen tsc --noEmitund üben Sie die API Form gegen einen Mock oder ein Vertragswerkzeug aus, bevor Sie miteinander fusionieren. Wenn Sie die Generatorversion in package.jsonzwei Ingenieure können nicht versehentlich unterschiedliche Ausgaben aus demselben Spezifik erzeugen.

Einfache GitHub-Actions-Form

Ein praktischer Workflow sieht so aus:

  1. Die Spezifikation aus dem Repository oder der generierten Quelle ziehen.
  2. Regenerieren Sie die Typen.
  3. Die Aufgabe fehlschlagen, wenn git diff zeigt Änderungen.
  4. Laufen tsc --noEmit.
  5. Ein Vertragstest gegen einen Mock-Server wie Prism oder einem Spectral-gestützten Check ausführen.

The key difference between contract tests and snapshot tests is scope. Snapshots often tell you the file changed. Contract tests tell you whether the shape still behaves like the spec says it should.

A mock server is especially useful when backend and frontend work are separated by time or team boundaries. It gives consumer code a predictable API surface while still checking the actual contract rather than a hard-coded fixture. The continuous integration setup guide ein nützliches Referenzwerkzeug, wenn Ihr Team noch einen sauberen, wiederholbaren CI-Baseline benötigt.

Pinning the generator version avoids one of the nastiest failures in codegen pipelines, invisible output skew. If one developer upgrades the generator locally and another doesn’t, the generated file can become a source of random noise instead of signal. CI should make that impossible.

The result is a pipeline where schema changes, type generation, compiler checks, and contract tests all reinforce one another. That’s what makes the workflow honest.

Maintenbare Pipelines, Leistung und ein letzter Checkliste

Eine Checkliste mit vier wichtigen Schritten zur Wartung einer OpenAPI TypeScript-Pipeline für Softwareentwicklungsprojekte.

Die Pipelines, die überleben, sind diejenigen mit unterhaltsamer Governance. Die Spezifikation versionieren, die Schemaänderungen wie code wie code überprüfen, den Generator festlegen und dokumentieren, wie sich Bruchänderungen genehmigen lassen. Wenn der Prozess unscharf ist, werden die Leute daran herumgehen und dann werden die generierten Typen zu Dekorationen anstatt zur Durchsetzung.

Eine Handvoll Leistungsknöpfe zählen wirklich

Die inkrementelle Erzeugung hilft in Monorepos, wo die Spezifikation oft ändert, aber nur ein Paket sie konsumiert. tsc --incremental Kann wiederholte Compilerarbeit streichen und die Ausgabe von Flags, die Sie in Produktionsbuilds nicht benötigen, deaktivieren, um die generierte Oberfläche kleiner zu halten. In der Praxis ist der größte Gewinn immer noch sozial und nicht technisch, weil ein vorhersehbarer Pipeline häufiger ausgeführt wird als ein cleverer.

Die folgende Checkliste ist diejenige, die Sie sich merken sollten:

  • Versionspinning: Die openapi-typescript Version festlegen package.json So der Ausgabebereich bleibt auf allen Maschinen gleich.
  • Schema-Überprüfung: Ändern Sie Spezifikationsänderungen wie verhandelbare Vertragsänderungen, nicht wie Hauswirtschaft.
  • Drift-Detektion: Regenerate in CI und fehlschlagen bei Diff.
  • Edge-Validierung: Analysiere unvertraute Payloads, bevor sie das Anwendungsstate oder die Persistenz erreichen.
  • Vertragsprüfung: Führe einen mock-gestützten Test durch, der beweist, dass der Verbraucher code immer noch dem Schema entspricht.
  • Politisierung von Änderungen: Beschreibe, wer die Änderungen der Form genehmigt und wie die Kunden benachrichtigt werden.

Ein Pipeline, die diese Schranken enthält, generiert nicht nur Typen, sondern macht den Vertrag sichtbar. Diese Sichtbarkeit ist es, die den Teams verhindert, ein File zu vertrauen, das nur sicher aussieht.

Wenn Sie Apps mit Capacitor oder Electron versenden und Ihr Update-Pipeline mit der gleichen Disziplin verhalten möchte, bietet Capgo Ihnen einen praktischen Weg, JavaScript, CSS, Kopien, Konfigurationen und Asset-Änderungen schnell ohne auf die App-Store-Überprüfung zu warten. Besuchen Sie Capgo um zu sehen, wie seine signierten Pakete, die Rückschlagschutzfunktion und die Freigabekontrollen in einen Freigabeprozess passen, der ohne Kontrolle schnell sein muss.

Live-Updates für Capacitor-Apps

When a web-layer bug is live, ship the fix through Capgo instead of waiting days for app store approval. Users get the update in the background while native changes stay in the normal review path.

Neueste aus unserem Blog

Capgo bietet Ihnen die besten Einblicke, die Sie benötigen, um eine wirklich professionelle Mobilanwendung zu erstellen.