🧭OpenAPI in der Praxis
Was man beim Schreiben und Pflegen einer API-Beschreibung beachten sollte – und wofür OpenAPI nicht gedacht ist.
🏷️Versionierung und Breaking Changes
| Änderung | Breaking? | Warum |
|---|---|---|
| Neues optionales Feld in einer Antwort | ✅ nein | Clients ignorieren unbekannte Felder (sollten sie jedenfalls). |
| Neuer optionaler Query-Parameter | ✅ nein | Alte Anfragen bleiben gültig. |
| Neuer Endpunkt / neue Operation | ✅ nein | Bestehende Aufrufe ändern sich nicht. |
| Feld in der Antwort entfernen oder umbenennen | 💥 ja | Clients, die es lesen, brechen. |
| Optionales Request-Feld wird required | 💥 ja | Alte Anfragen werden mit 400 abgelehnt. |
| Typ ändern (integer → string) | 💥 ja | Deserialisierung und generierte Typen brechen. |
| Neuer Wert in einem Antwort-enum | 💥 ja | Umstritten: streng typisierte Clients (switch ohne default) scheitern – vorher ankündigen. |
| Pfad oder operationId ändern | 💥 ja | URLs und generierte Funktionsnamen ändern sich. |
deprecated: true gibt es an Operationen, Parametern und Schemas (3.2 auch an Security Schemes). Generatoren machen daraus@deprecated-Hinweise; der HTTP-Header Sunset (RFC 8594) nennt das Abschaltdatum.✅Best Practices
- 🧩 Alles Wiederkehrende nach components: Fehlerantworten, Paging-Parameter, gemeinsame Schemas.
- 🏷️ Sprechende, eindeutige operationIds im camelCase (
listBooks,createOrder) – daraus werden Funktionsnamen. - 📝 summary kurz, description ausführlich; jedes Feld mit Beschreibung und Beispiel.
- 🚦 Alle relevanten Statuscodes dokumentieren, Fehler einheitlich (Problem Details, RFC 9457).
- 🔒 Security global setzen und öffentliche Operationen gezielt mit
security: []freigeben – sicherer als umgekehrt. - 🧪 In der CI prüfen: Lint (Spectral/Redocly), Beispiele gegen Schemas, Breaking-Change-Diff, Vertragstests.
- 📂 Große Beschreibungen aufteilen (externe $ref) und für die Auslieferung bündeln.
components:
parameters:
Limit:
name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
Cursor:
name: cursor
in: query
schema: { type: string }
schemas:
BookPage:
type: object
required: [items]
properties:
items:
type: array
items: { $ref: '#/components/schemas/Book' }
nextCursor:
type: [string, 'null'] # null = letzte Seite🐞Häufige Fehler
❗ openapi: 3.1 ohne Anführungszeichen
YAML liest eine Zahl. Immer als Text: openapi: 3.1.1 (Patch-Version angeben) bzw. version: '1.0'.
❗ Pfadparameter nicht deklariert
{id} im Pfad braucht einen Parameter name: id, in: path, required: true.
❗ nullable in 3.1
Wird als unbekanntes Schlüsselwort ignoriert. Richtig: type: [string, 'null'].
❗ $ref mit Geschwistern in 3.0
description/example neben $ref werden ignoriert – Workaround allOf: [ { $ref: … } ].
❗ Beispiele passen nicht zum Schema
Mock-Server liefern dann ungültige Daten. Beispiele in der CI gegen das Schema prüfen.
❗ Statuscodes als Zahl
Unquotiert liest YAML 200 als Zahl. Die Spezifikation verlangt Anführungszeichen ('200') für die Kompatibilität zwischen JSON und YAML – viele Parser sind nur tolerant.
❗ Keine Fehlerantworten beschrieben
Nur 200 dokumentiert → Clients wissen nicht, wie 400/401/404 aussehen. Einheitlich z. B. mit Problem Details (RFC 9457).
❗ Geheimnisse in Beispielen
Echte Tokens, Hosts oder E-Mail-Adressen haben in einer veröffentlichten Spezifikation nichts verloren – example.org und Platzhalter verwenden.
Viele davon findet der Validator im Editor – laden Sie dort das Beispiel „🐞 Mit Fehlern“.
🧭Abgrenzung: OpenAPI, AsyncAPI, GraphQL, JSON:API, MCP
| Standard | Beschreibt | Format | Typischer Einsatz |
|---|---|---|---|
| OpenAPI | Synchrone HTTP-APIs (Request → Response), meist REST-artig | YAML/JSON, JSON Schema | Öffentliche und interne Web-APIs, SDK-Generierung |
| AsyncAPI | Ereignisgetriebene APIs: Kanäle und Nachrichten über Kafka, MQTT, AMQP, WebSocket … | YAML/JSON, an OpenAPI angelehnt | Messaging, Event-Streaming, IoT |
| GraphQL | Eine Abfragesprache mit einem Endpunkt; der Client wählt die Felder | SDL (Schema Definition Language), Introspection | Frontends mit vielen unterschiedlichen Datenbedarfen |
| JSON:API | Konvention für das Format von JSON-Antworten (data, relationships, included, Paginierung) | Medientyp application/vnd.api+json | Ergänzt OpenAPI: legt fest, WIE die Nutzdaten aussehen |
| MCP | Model Context Protocol: KI-Assistenten rufen Werkzeuge, Ressourcen und Prompts eines Servers auf (JSON-RPC 2.0) | JSON-RPC, Werkzeug-Eingaben als JSON Schema | LLM-Integrationen; aus einer OpenAPI-Datei lassen sich MCP-Werkzeuge ableiten |
synchron (Anfrage → Antwort) asynchron (Ereignisse)
┌─────────────────────────────┐ ┌──────────────────────┐
Vertrag │ OpenAPI GraphQL (SDL) │ │ AsyncAPI │
└─────────────────────────────┘ └──────────────────────┘
Nutzdaten JSON:API legt das Format der JSON-Dokumente fest (passt zu OpenAPI)
KI MCP: Werkzeuge für LLMs – deren Eingaben sind ebenfalls JSON Schema