Stabile REST APIs – Versionierung, SemVer und Migration
APIs verändern sich – neue Felder kommen hinzu, Formate werden klarer, Fehlercodes präziser. Ohne Versionierung führt das schnell zu Breaking Changes und frustrierten Clients. Ziel ist, weiterzuentwickeln, ohne bestehende Integrationen zu brechen.
Die gute Nachricht: Mit ein paar Spielregeln und einer passenden Versionierungsstrategie bleibt deine API stabil und gleichzeitig lern- und releasefähig. In diesem Leitfaden lernst du die gängigen Optionen kennen, bekommst klare Beispiele und einen Fahrplan, wie du Änderungen sicher ausrollst.
Warum Versionierung
Versionierung schafft Vorhersehbarkeit. Clients wissen, welches Verhalten sie erwarten dürfen. Teams können iterativ liefern, Deprecations kommunizieren und Migrationen planen. Ohne Versionsmodell werden selbst kleine Änderungen zur Risikooperation.
Grundregeln für Änderungen
Halte dich an diese drei Prinzipien und du vermeidest 80 Prozent der Probleme:
- Additiv vor destruktiv: Felder hinzufügen ist meist abwärtskompatibel. Felder entfernen oder Bedeutungen ändern nicht.
- Defaults stabil halten: Neue Felder sollten optionale Defaults haben.
- Fehlerformat konstant: Fehler-Shape (z. B.
code,message,details) bleibt gleich – du kannst neue Codes hinzufügen, aber nicht das Grundformat brechen.
Versionierungs-Strategien im Überblick
Pfadversionierung – simpel und sichtbar
Die Version steckt im URL-Pfad.
GET /v1/orders/123
GET /v2/orders/123
Vorteile: Einfach, gut sichtbar, leicht zu cachen.
Nachteile: Version steht in jeder Route, mehrere Routenpfade pro Ressource.
Empfehlung: Für Einsteiger und Public APIs oft die beste Wahl.
Headerversionierung – sauber für Profis
Die Version steckt in HTTP-Headern. Zwei gängige Varianten:
- Custom Header:
X-API-Version: 2 - Media-Type Versioning (Content Negotiation):
Accept: application/vnd.example.orders-v2+json
Vorteile: API-URLs bleiben stabil, Version verhandelbar.
Nachteile: Debug und Caching komplexer, Clients brauchen Header-Kontrolle.
Empfehlung: Für private oder Enterprise APIs, wenn du flexibel bleiben willst.
Query-Parameter – pragmatisch, aber zweitbeste Wahl
GET /orders/123?v=2
Vorteile: Einfach hinzuzufügen.
Nachteile: Caching und Semantik schwächer als Pfad oder Header.
Empfehlung: Nur, wenn Pfad/Header nicht möglich sind.
SemVer für APIs – sinnvoll einsetzen
Nutze SemVer-Denken für dein API-Verhalten:
- MAJOR (v1 → v2): Breaking Changes.
- MINOR (v1.1): Additive Features, neue Felder, neue Endpunkte.
- PATCH (v1.0.1): Bugfixes ohne Vertragsänderung.
Tipp: Exponiere nach außen v1, v2 im Pfad oder Header. Minor/Patch dokumentierst du im Changelog, aber änderst die Version-Markierung nach außen nicht zwingend.
Beispiele aus der Praxis
Pfadversionierung mit Express.js
const app = require("express")();
// v1 - schlanke Order-Ansicht
app.get("/v1/orders/:id", (req, res) => {
res.json({ id: req.params.id, total: 42.50, currency: "EUR" });
});
// v2 - mehr Details, abwärtskompatibel zu v1-Clients
app.get("/v2/orders/:id", (req, res) => {
res.json({
id: req.params.id,
total: 42.50,
currency: "EUR",
items: [{ sku: "ABC-1", qty: 1, price: 42.50 }]
});
});
app.listen(3000);
Media-Type Versioning mit cURL
curl -H "Accept: application/vnd.example.orders-v1+json" https://api.example.com/orders/123
curl -H "Accept: application/vnd.example.orders-v2+json" https://api.example.com/orders/123
Wichtig: v2 erweitert v1 additiv. v1-Clients funktionieren weiter, wenn sie neue Felder ignorieren.
Deprecation und Sunset – fair kommunizieren
Deprecation-Header setzen
Informiere Clients frühzeitig über geplante Abschaltungen:
Deprecation: true
Sunset: Wed, 19 Feb 2026 00:00:00 GMT
Link: </docs/migrate-v1-to-v2>; rel="deprecation"; type="text/html"
Effekt: Clients sehen früh, dass v1 ausläuft, und finden direkt den Migrationsleitfaden.
Zeitplan und Migration
- Ankündigen in Release Notes und E-Mail.
- Parallelbetrieb (z. B. v1 und v2) mindestens 6-12 Monate.
- Testumgebung für v2 bereitstellen, inklusive Beispieldaten.
- Monitoring der v1-Nutzung, gezielte Reminder.
Kontrakte testen – Stabilität sichern
OpenAPI als Vertrag
Pflege eine OpenAPI-Spezifikation pro Hauptversion. Nutze Contract Tests, damit Implementierung und Spezifikation deckungsgleich bleiben.
Kompatibilitäts-Checks
Automatisiere Checks, die Breaking Changes erkennen: Feld entfernt, Typ geändert, Pflichtfeld hinzugefügt. Scheitere Builds, wenn die Stabilitätsregeln verletzt werden.
Fehlerformat und Pagination über Versionen
Fehler stabil halten
Ein konstantes Fehlerobjekt hilft Clients enorm:
{ "code": "ORDER_NOT_FOUND", "message": "Order not found", "details": null }
Du kannst neue Codes ergänzen, aber Keys sollten gleich bleiben.
Pagination nicht brechen
Wechsle nicht plötzlich von page/size auf cursor in derselben MAJOR. Führe Cursor Pagination z. B. erst mit v2 ein und dokumentiere beide Modelle sauber.
Entscheidungshilfe – was passt zu dir
Nimm Pfadversionierung, wenn
du schnell starten willst, Public bedienst und klare Sichtbarkeit brauchst. Sie ist einfach und SEO/logfreundlich.
Nimm Headerversionierung, wenn
du Enterprise-Kontexte hast, URLs stabil halten willst und Content Negotiation schon nutzt.
Nimm Query-Parameter nur, wenn
du keine Kontrolle über Pfad oder Header hast und eine pragmatische Lösung brauchst.
Häufige Fehler – kurz vermeiden
Alles in v1 lassen und doch brechen – besser v2 einführen.
Felder umbenennen statt neue Felder hinzugefügen – vermeide das in derselben MAJOR.
Keine Deprecation-Kommunikation – setze Header und Docs-Links.
Fehlerformat ändern – halte das stabil.
Fazit
Mit einer klaren Versionierungsstrategie bleiben deine REST APIs verlässlich und weiterentwickelbar. Pfad ist für Einsteiger oft der beste Start, Header spielt seine Stärken in Enterprise-Umgebungen aus. Kombiniere das mit SemVer-Denken, Deprecation/Sunset-Headern, OpenAPI und automatischen Kompatibilitätsprüfungen. So lieferst du neue Funktionen, ohne bestehende Clients zu brechen.



Hinterlasse einen Kommentar
An der Diskussion beteiligen?Hinterlasse uns deinen Kommentar!