Zum Hauptinhalt springen
Entwicklung Mobil

OpenAPI TypeScript: Erstellen Sie Typen, Clients und Validierung

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

Martin Donadieu

Martin Donadieu

Inhaltsmarketer

OpenAPI TypeScript: Erstellen Sie Typen, Clients und Validierung

Sie können normalerweise den Moment erkennen, an dem ein API Pipeline anfängt, der Team 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 den Fehler wegnimmt. Das ist das OpenAPI TypeScript-Problem, nicht, ob ein Generator Schnittstellen ausstoßen kann.

Die nützliche Frage ist schwieriger. Was ist der Vertrag zwischen Schema, Transport und Validierung, und welche Teile sollten schnell in der Buildzeit scheitern, anstatt in der Laufzeit zu lecken? Sobald Sie das Rahmen OpenAPI TypeScript als Pipeline-Option werden die Vor- und Nachteile deutlicher und die Werkzeuge stoppen, die Lösung zu sein.

Inhaltsverzeichnis

Warum generierte Typen nicht dasselbe sind wie ein sicheres API

Ein Teamkollege fusioniert einen PR, der eine optionale Antwortfeld hinzufügt. Das 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 versehen wurde, as anyund die Produktion beginnt, als ob der Vertrag nie geändert wurde.

Das ist der Haken mit generierten Typen. TypeScript kann nur den code schützen, der die generierten Typen konsumiert, und nur, wenn der Transportlayer den Vertrag nicht wieder löscht. Die OpenAPI-Seite gibt Ihnen ein Schema, nicht eine Garantie, dass jeder Aufrufer es respektiert. Die Diskussion um die Verständigung von API-Verbindungen ist hier nützlich, weil sie die Konversation von einer einzelnen Werkzeug entfernt und sich auf die Weise beschäftigt, wie Systeme miteinander verbunden sind.

Wo die Misserfolge verborgen sind

Die häufigsten Unterbrechungen sind langweilig, nicht exotisch. Schema drift tritt auf, wenn die OpenAPI-Spezifikation und der bereitgestellte Dienst nicht mehr übereinstimmen. Teilweise Abdeckung 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 einen lockeren Antworttyp verwendet.

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

There ist auch eine Laufzeitlücke. TypeScript-Typen verschwinden nach der Kompilierung, sodass sie nicht auf fehlerhaftes JSON reagieren können, das über das Netzwerk übertragen wird. Das Netzwerk interessiert sich nicht für die Annahmen Ihres Editors, und das ist der Grund, warum ein generierter Client nur eine Schicht in einer sicheren API Pipeline ist.

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

openapi typescript zu denken ist diese. Es gibt Ihnen eine strenge Schema-zu-Typen-Brücke, was ausgezeichnet ist, aber es überprüft keine Anfragen, erzwingt keine Laufzeit-Payload-Form, oder stoppt einen schlampigen Wrapper, der alles untergräbt. Der Generator ist der leichteste 20 Prozent. Der Rest ist die Pipeline-Design, und das ist, wo Teams entweder Vertrauen gewinnen oder falsche Zuversicht anhäufen. Typen aus einer OpenAPI-Spezifikation generieren

Bild von https://openapi-ts.dev

Die leichte nützlichste Konfiguration ist normalerweise die, die realen Repo-Churn überlebt. Halten Sie die OpenAPI-Spezifikation im gleichen Repository, generieren Sie ein verpflichtetes Typ-File und machen Sie den Drift in CI sichtbar, anstatt auf jemanden zu zählen, der sich an einen Refresh-Schritt erinnert. Ein Befehl wie

gibt Ihnen ein deterministisches Ausgabedatei, die Reviewer wie jede andere Quelländerstellung inspizieren können. npx openapi-typescript ./openapi.yaml -o ./src/types/api.d.ts Die Flags, die tatsächlich zählen

__CAPGO_KEEP_0__ ist ein Sicherheitsstandard für App-Store-Kompliance

The Ausgabeflagge ist wichtig, weil sie die generierte Artefakt explizit macht. -o ist nützlich, wenn Sie die generierten Typen dazu bringen möchten, die readonly-Intention im Ausgabebereich zu bewahren, und --immutable stabilisiert Diffs, wenn die Schema-Reihenfolge ohne semantische Bedeutung ändert. --alphabetize wird wichtig, wenn Ihr Team Vorzüge in der generierten Oberfläche in Enums statt in Vereinigungen bevorzugt. --enum Die Dokumentation des Projekts ist klar über den Umfang, es ist ein

Typgenerator , 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 offene Quellcode-Werkzeuge in der Produktion halten können, wenn die Dokumentation und Releases aktiv bleiben, wie inder Fall für die offene Quellcode-Wartung diskutiert wird. Ein praktischer Lesetipp zu dieser Haltung ist das Projekt’s__CAPGO_KEEP_0__ Repository und __CAPGO_KEEP_1__ Dokumentation GitHub repository and CLI documentation.

Wire-Generierung in package.json so die Kommandozeile lebt neben den anderen Build-Skripten, dann wird sie ausgeführt, sobald sich die Spezifikation ändert. In CI wird das File neu generiert und wenn git diff zeigt Abweichung. Das wandelt Änderungen an Verträgen in sichtbare Überprüfungsarbeit statt in stumme Laufzeitrisiken.

Die Seiten des Schemas sind genauso wichtig wie die Kommandozeile. Das Projekt empfiehlt compilerOptions.noUncheckedIndexedAccess so additionalProperties wird T | undefined, die sicherere Indexierung an Aufrufstellen erzwingt. Es empfiehlt auch, oneOf solo anstelle von der Mischung mit zusätzlicher Komposition zu verwenden, und $defs am Root zu behalten, wenn die Platzierung unsicher ist, weil falsch platzierte Definitionen aus der generierten Ausgabe verschwinden können. Ein weiterer Detail spart Zeit später, openapi-typescript wird nie any, also wird die fehlende Schema-Detail frühzeitig an die Oberfläche gebracht anstatt unter permissiven Typen versteckt.

Halte die Spezifikation explizit, oder der Generator wird die Ambiguität treu wieder zurückgeben.

Das Workflow, das überlebt, ist einfach. Stelle die Spezifikation unter Versionskontrolle, regenere auf Build, commite die generierte Datei und lasse den Typ-Checker vorher klagen, wenn jemand eine Mismatch zusammenfügt. Das gibt dir eine stabile Vertragsgrenze für den Rest der Pipeline.

Zwischen reinen Typen, vollständigen Clients und keinem Codegenerierung wählen

Muster Buildzeit Ausgabedateien Bundle-Größe Beste Wahl
Reine Typen mit dünner Wrapper Schnell Wenig Niedrig Teams, die Kontrolle und kleine Laufzeitoberfläche wollen
Vollständige Client-Codegenerierung Langsamer Viele Höher Teams, die eine schnelle Übergabe und automatisierte Operationen bevorzugen
Keine Anforderungsbauern für Code-Generierung Schnell Keine oder minimale Niedrig Einreihen-Apps, die handgeschriebene Transportlogik bevorzugen

Die Wahl ist nicht wirklich "welches Werkzeug gewinnt". Es ist vielmehr welche Pipeline-Form Ihren Code, Ihr Team und wie viel Änderungen der API sieht. In einer 2025-Benchmark um einen großen OpenAPI-Spezifikation 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, während auch eine einzelne Ausgabedatei gegenüber 16 für hey-api, 2,719 für Orvalund 3,877 für Kubb (Benchmarkdetails).

Rein-Typen bevorzugen die Kontrolle

Ein rein-typen-Setup passt gut zu einer handschriftlichen Anforderungs-Schicht, da man die Laufzeit klein und die API Oberfläche langweilig halten kann. Das ist in bundler-sensitive Frontends und in Apps wichtig, in denen eine Team beide die Spezifikation und den Verbraucher besitzt. Wenn Sie sich daran erinnern müssen, dass die Entwicklererfahrung nicht nur Syntaxzucker ist, der Entwicklererfahrungswinkel ist einfacher zu beurteilen, wenn Ihr Client code kurz, offensichtlich und überprüfbar ist.

Vollklienten bevorzugen die Handover-Geschwindigkeit

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

Keine Codegenerierung bevorzugt lokale Refaktoren

Typisierte Anforderungsbaustellen und fetch Wann eine Codebasis beide Enden der Formung besitzt und die API-Änderungen eng koordiniert sind, funktionieren Wrapper gut. Der Nachteil ist die Pflege-Discipline. Je mehr Teams und Repositories zwischen Produzent und Verbraucher liegen, desto wahrscheinlicher driftet eine manuell geschriebene Anfrage-Schicht, es sei denn, Sie setzen aggressive Vertrags-Tests ein.

Das Kernentscheidungspunkt ist nicht ideologisch. Wenn Ihr Paketbudget knapp ist, sind reine Typen attraktiv. Wenn Ihr Team maximalen Aufbau und die Ausgabe absorbieren möchte, reduzieren vollständige Clients die Einrichtungszeit. Wenn Sie minimal bewegliche Teile und den Vertrag nahe halten möchten, können no-codegen-Anfrage-Builder die richtige interne Abwägung sein.

Ein Thin-Typed-Client um Fetch oder Axios zu bauen

Eine Diagramm, das einen mit generierten TypeScript API-Definitionen für Web-Anfragen arbeitenden Typisierten Client Wrapper-Prozess illustriert.

Eine dünne Abdeckung ist der Punkt, an dem der Generator aufhört und Ihre Anwendung code beginnt. Die Abdeckung sollte eine Funktion pro Operation offenlegen, die getippte Parameter und Abfrageobjekte akzeptieren und den Aufruf an eine fetch oder eine injizierte axios Instanz weiterleiten, ohne versucht zu sein, clever zu sein. In den meisten Produktionskonfigurationen bleibt diese Schicht um 30–60 Zeilen herum, weil die generierten Typen bereits den größten Teil der Formung tragen.

Hier ist das mentale Modell, das hält:

  • Path-Parameter bleiben getippt so /users/{id} kann nicht ohne einen id.
  • Query-Objekte bleiben typisiert so werden optionalen Filtern nicht in eine Brühe aus Zeichen umgewandelt.
  • Antwortkörper bleiben typisiert so kann man sich bei der Verarbeitung von code auf die enge Form verlassen, die er erwartet.

Ein Wrapper wie dieser ist absichtlich langweilig. Er sollte weder Wiederholungen, Transformationen noch Auth-Politiken erfinden, wenn diese an anderer Stelle gehören. Er sollte die Anfrage von einem typisierten Operation in den Transportlayer übertragen und dann den typisierten Ergebnis wieder nach oben übergeben.

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

Die häufigste Fehlhandlung besteht darin, Mismatches mit as any zu überdecken, wenn die generierten Typen nicht mit dem alten Wrapper-Signatur übereinstimmen. Das kauft einem eine grüne Build und ein fragiles App. Es versteckt auch die Vertragsverletzung, die du mit dem Generator aufdecken wolltest.

Für Teams, die Axios bevorzugen, ist das Muster gleich, nur die Implementierung des Transportlayers ändert sich. Für Teams, die einfache Browser-Seiten code bevorzugen, fetch ist oft ausreichend. Das Wichtige ist, dass die Anfrage-Funktion den generierten Pfad-Typ akzeptiert und einen typisierten Antwortkörper zurückgibt, nicht einen lose geformten Objekt, das später massiert wird.

Wenn du diesen Schnittstelle gut nutzt, openapi typescript gibt Ihnen eine saubere Arbeitsteilung. Die Schema lebt im Spezifikation, der Transport lebt im Wrapper, und die App sieht statische Operationen anstatt ad-hoc-Anfragen code.

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

Typsicherheitsinformationen von TypeScript verschwinden bei Laufzeit, und das Netzwerk kümmert sich nicht um die Zuversicht Ihres Editors. Deshalb ist das sichere Muster nicht „Typen generieren und hoffen“, sondern „Typen generieren, dann validieren an der Grenze, an der unvertrauenswürdige Daten in die App eintreten“. Das generierte Schema bleibt die Quelle der Wahrheit, und Validierungsbibliotheken wie zod, ajv, und io-ts handeln die Grenzprüfungen, die Zeit- und Platz-Überprüfungen nicht können.

Validieren, wo die Daten eintreten

Für React-Apps ist die Grenze normalerweise direkt nach der Anfrageauflösung und bevor der Payload in den Zustand eingeht. Für Server ist es, bevor der Payload in eine Datenbank geschrieben wird oder einer Geschäftsregel übergeben wird. Die Regel ist einfach, die Validierung in der Nähe der Grenze halten und keine manuellen Prüfungen durch die Funktion code.

A zod eine Form kann die generierte Antwortform ohne sie zu ersetzen spiegeln:

import { z } from "zod";

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

Dieses Beispiel validiert die Felder, die das Schema als optional markiert hat, und es hält die Laufzeitprüfung mit dem von dem Generator produzierten ausgerichtet. ajv ist eine starke Wahl, wenn Sie eine hohe Durchsatz-JSON-Schema-Validierung auf dem Server benötigen, während io-ts passt noch Teams, die bereits in einem bestimmten Stil leben. fp-ts Der große Fehler ist, zu spät zu validieren. Wenn der Payload in Ihr App zuerst kommt, ist der Typsystem bereits umgangen und der Fehler hat einen Platz, um sich zu verstecken. Ein kurzer Leitfaden zu

Einheiten-Tests für JavaScript passt gut zu diesem Mindset, weil 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 den Laufzeit-Payload, und Ihre App __CAPGO_KEEP_0__ sieht nur Daten, die beide Schritte überstanden haben. Das ist ein viel besseres Grenzwert als das Vertrauen in einen statischen Typ, der einen unvertrauenswürdigen Antwort polizieren soll. generates the contract, the validator checks the runtime payload, and your app code only sees data that survived both steps. That’s a much better boundary than trusting a static type to police an untrusted response.

Bild von https://__CAPGO_KEEP_0__.com

Screenshot from https://github.com

, und üben Sie die __CAPGO_KEEP_0__ Form gegen einen Mock oder einen Vertrags-Tool aus, bevor Sie miteinander fusionieren. Wenn Sie die Generator-Version festlegen tsc --noEmitEin Pipeline, der anhalten bleibt, verwandelt den Vertrag in eine Barriere, nicht in eine Empfehlung. Regenerieren Sie die Typen, scheitern Sie bei der Drift, führen Sie , und üben Sie die API Form gegen einen Mock oder einen Vertrags-Tool aus, bevor Sie miteinander fusionieren. Wenn Sie die Generator-Version festlegen package.jsonZwei Ingenieure können nicht versehentlich unterschiedliche Ausgaben aus derselben Spezifikation produzieren.

Eine einfache GitHub Actions-Form

Ein praktischer Workflow sieht so aus:

  1. Ziehen Sie die Spezifikation aus dem Repository oder der generierten Quelle.
  2. Regenerieren Sie die Typen.
  3. Beenden Sie das Job, wenn git diff zeigt Änderungen.
  4. Ausführen tsc --noEmit.
  5. Ein Vertrags-Test gegen einen Mock-Server wie Prism oder einen Spectral-gestützten Prüfsatz ausführen.

Der Hauptunterschied zwischen Vertragsprüfungen und Snapshot-Tests besteht im Umfang. Snapshots erzählen Ihnen oft, dass der Datei geändert wurde. Vertragsprüfungen erzählen Ihnen, ob die Form noch so verhält, wie die Spezifikation sagt, sie sollte.

Ein Mock-Server ist besonders nützlich, wenn Backend- und Frontend-Arbeit durch Zeit- oder Teamgrenzen getrennt sind. Er bietet dem Verbraucher code eine vorhersehbare API Oberfläche, während er den tatsächlichen Vertrag anstatt einer festgelegten Vorlage überprüft. Die Anleitung zur kontinuierlichen Integration ist eine nützliche Referenz, wenn Ihr Team noch immer eine saubere, wiederholbare CI-Basis benötigt.

Das Fixieren der Generatorversion vermeidet eine der schlimmsten Fehler in Code-Generierung-Pipelines, die unsichtbare Ausgabeschwankungen. Wenn ein Entwickler die Generator lokal aktualisiert und ein anderer nicht, kann das generierte Datei zu einem Quell der zufälligen Lärm statt Signal werden. Die CI sollte das unmöglich machen.

Das Ergebnis ist ein Pipeline, in der Schemaänderungen, Typgenerierung, Compilerprüfungen und Vertragsprüfungen sich gegenseitig verstärken. Das ist das, was den Workflow ehrlich macht.

Halbwegs Wartbare Pipelines, Leistung und ein Abschlusscheckliste

Eine Checkliste, die vier wichtige Schritte für die Wartung einer OpenAPI-Pipeline für TypeScript-Projekte zeigt.

Die Pipelines, die überleben, sind diejenigen mit langweiliger Governance. Versionieren Sie die Spezifikation, überprüfen Sie Schemaänderungen wie code, fixieren Sie den Generator und dokumentieren Sie, wie sich verändernde Änderungen genehmigen lassen. Wenn der Prozess unscharf ist, werden die Leute daran herumgehen, und dann werden die generierten Typen zu Dekorationen statt zur Durchsetzung.

Einige Leistungsknöpfe haben tatsächlich Auswirkungen

Die inkrementelle Generierung hilft in Monorepos, in denen die Spezifikation oft ändert, aber nur ein Paket sie konsumiert. tsc --incremental Kann wiederholte Compilerarbeit reduzieren 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, nicht technisch, weil eine vorhersehbare Pipeline häufiger als eine clevere ausgeführt wird.

Die unten stehende Checkliste ist diejenige, die Sie sich merken sollten:

  • Version-Fixierung: Die Generatorversion fixieren, um eine der schlimmsten Fehler in Code-Generierung-Pipelines zu vermeiden, die unsichtbare Ausgabeschwankungen sind. Wenn ein Entwickler die Generator lokal aktualisiert und ein anderer nicht, kann das generierte Datei zu einem Quell der zufälligen Lärm statt Signal werden. Die CI sollte das unmöglich machen. openapi-typescript Version in package.json Dadurch wird sichergestellt, dass die Ausgabe nicht zwischen Maschinen schwebt.
  • Schema-Übersicht: Behandeln Sie Änderungen an der Spezifikation als veränderbare Vertragsänderungen und nicht als Hauswirtschaft.
  • Drift-Detektion: Regenerieren Sie in CI und schließen Sie auf Differenz.
  • Edge-Validierung: Analysieren Sie unvertrauene Payloads, bevor sie das Anwendungsstatus oder die Persistenz erreichen.
  • Vertragsprüfung: Führen Sie eine mit Mocks unterstützte Überprüfung durch, die beweist, dass der Konsumierer code noch immer mit der Schema übereinstimmt.
  • Policy für Bruchstellenänderungen: Legen Sie fest, wer die Änderungen an der Form genehmigt und wie die Kunden benachrichtigt werden.

Eine Pipeline, die diese Schaltungen enthält, erzeugt nicht nur Typen, sie macht das Vertragsverhältnis sichtbar. Diese Sichtbarkeit ist es, was den Teams verhindert, ein Datei zu vertrauen, die nur sicher aussieht.

Wenn Sie Capacitor oder Electron-Apps verschicken und Ihr Update-Pipeline so diszipliniert verhalten möchte wie Ihr Capgo-Paket, gibt es Ihnen einen praktischen Weg, JavaScript, CSS, Kopien, Konfiguration und Asset-Fixes schnell ohne Wartezeit auf die App-Store-Bewertung zu bewegen. Besuchen Sie Capgo um zu sehen, wie seine signierten Pakete, die Rückschlagschutz und die Freigabekontrollen in einen Freigabeprozess passen, der ohne Kontrolle schnell sein muss.

Live-Updates für Capacitor-Anwendungen

Wenn ein Bug im Web-Schicht lebt, versenden Sie die Reparatur über Capgo anstatt Tage auf App-Store-Zustimmung zu warten. Die Benutzer erhalten die Aktualisierung im Hintergrund, während native Änderungen im normalen Review-Verfahren bleiben.

Loslegen

Neuestes aus unserem Blog

Capgo gibt Ihnen die besten Einblicke, die Sie benötigen, um eine wirklich professionelle mobile App zu erstellen.