In 0202 haben wir die Formen der Antworten von Hand nachgeschrieben. Das hält, bis die API sich ändert: Ein umbenanntes Feld bemerkt dann niemand, bis ein Besucher eine leere Spalte sieht. Besser ist es, den Weg umzukehren: Die API beschreibt sich in einem OpenAPI-Dokument (K2 2.3.10), dieses Dokument ist der Vertrag (K2 2.12.2), und der Client wird daraus erzeugt. Die Lektion probiert fünf Werkzeuge am selben kleinen Dokument aus, entscheidet sich mit einer ADR für eines, stellt die Kontaktliste um und baut einen Test, der rot wird, wenn der Vertrag bricht.

Stand der Prüfung. Alles lief in einem Wegwerfprojekt außerhalb des Repositorys (Node 24.22.3, Angular 22.2.6, TypeScript 6.0.3, Vitest 5.1.0, .NET SDK 10.0.400, Java 11). Das Dokument openapi/kladde.json ist von Hand geschrieben und entspricht dem Vertrag des Kursplans (OpenAPI 3.1.1, 8 Operationen, 9 Schemas); es stammt nicht von einer laufenden API. Ausgeführt wurden ng-openapi-gen 1.1.0, @hey-api/openapi-ts 0.99.0, die Kiota-Kommandozeile 1.38.0, der OpenAPI Generator 7.27.0 (npm-Paket @openapitools/openapi-generator-cli 2.42.2) und openapi-typescript 7.13.0. Alle Ergebnisse außer dem von openapi-typescript wurden mit tsc übersetzt (Exit-Code 0); ng-openapi-gen ist in die Anwendung eingebaut (npm run build und ng test --no-watch, Exit-Code 0; Endstand nach 0204: 32 Tests in 7 Dateien). Der Kiota-Client lief in Node gegen einen kleinen eigenen Testserver (200 und eine 409 mit ProblemDetails). Nicht ausgeführt: die Erzeugung aus der Kladde-API selbst, Pipelines, Aufrufe der Clients von hey-api und OpenAPI Generator. Versionen und Lizenzen stammen von der npm-Registry am Schreibtag; die Lizenz der Kiota-Kommandozeile ist offen.

Der Vertrag zuerst

Der Vertrag beschreibt Wege, Parameter und Antworten, so wie die API sie anbietet. Er gehört der API; das Front End liest ihn und erzeugt seine Typen daraus, statt eine zweite Wahrheit zu pflegen. Das Dokument liegt im Repository des Front Ends als openapi/kladde.json (kopiert aus dem der API), die erzeugten Typen liegen nicht dort. Ändert sich der Vertrag, ändert sich der Client beim nächsten Build, und der Compiler zeigt jede Stelle, die ihn noch falsch versteht. Der Vertrag beschreibt die Form, nicht das Verhalten.