Was macht API-Versionierung & Abwärtskompatibilität?
Entwerfen Sie API-Versionierungsstrategien, die sich elegant weiterentwickeln, ohne bestehende Nutzer zu beeinträchtigen.
Aktivierungsauslöser
Aktivieren bei: „API-Versionierung“, „Abwärtskompatibilität“, „Auslauf (Deprecation)“, „Breaking Change“, „API-Migration“, „v1 v2“, „Sunset-Header“, „API-Evolution“, „Nicht-Breaking Change“
NICHT für: Datenschema-Evolution → schema-evolution-manager | Gateway-Versionsrouting → api-gateway-reverse-proxy-expert | GraphQL-Deprecation → graphql-server-architect
Kurzanleitung
- Änderung klassifizieren – additiv (sicher), Modifikation (ggf. Breaking), Entfernung (Breaking)
- Strategie wählen – URL-Pfad (
/v2/), Header (API-Version) oder Inhaltsverhandlung - Sunset-Header implementieren – RFC 8594 informiert Nutzer, wann alte Versionen auslaufen
- Versionen parallel betreiben – mindestens 6 Monate Überlappung für Hauptversionen
- Adoption überwachen – Traffic pro Version verfolgen, um den Ruhestand zu planen
Kernfähigkeiten
| Bereich | Technologien |
|---|---|
| URL-Versionierung | /api/v1/, /api/v2/ pfadbasiertes Routing |
| Header-Versionierung | API-Version: 2024-01-15, Accept-Version |
| Inhaltsverhandlung | Accept: application/vnd.myapi.v2+json |
| Auslaufverwaltung | Sunset-Header (RFC 8594), Deprecation-Header |
| Werkzeuge | OpenAPI 3.1 Overlays, Optic, Bump.sh |
Architekturmuster
Entscheidungsbaum für Versionierungsstrategie
Ist es nur additiv? (neue Felder, neue Endpunkte)
├─ JA → Kein Versionssprung nötig (abwärtskompatibel)
└─ NEIN → Handelt es sich um eine Feldumbenennung/Typänderung?
├─ JA → Können alte + neue Felder parallel existieren?
│ ├─ JA → Neues hinzufügen, altes auslaufen lassen (Nebenversion)
│ └─ NEIN → Hauptversionssprung (v1 → v2)
└─ NEIN → Handelt es sich um eine Entfernung?
└─ JA → Hauptversionssprung mit Auslauffrist
Parallele Versionseinführung
// Express-Router mit versionsbasiertem Routing
import { Router } from 'express';
const v1Router = Router();
const v2Router = Router();
// v1: gibt { name: string } zurück
v1Router.get('/users/:id', async (req, res) => {
const user = await getUser(req.params.id);
res.json({ name: user.fullName }); // legacy-Form
});
// v2: gibt { firstName, lastName, displayName } zurück
v2Router.get('/users/:id', async (req, res) => {
const user = await getUser(req.params.id);
res.json({
firstName: user.firstName,
lastName: user.lastName,
displayName: user.fullName,
});
});
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// Sunset-Header-Middleware für v1
v1Router.use((req, res, next) => {
res.set('Sunset', 'Sat, 01 Nov 2026 00:00:00 GMT');
res.set('Deprecation', 'true');
res.set('Link', '</api/v2>; rel="successor-version"');
next();
});
Datumsbasierte Versionierung (Stripe-Modell)
API-Version: 2026-03-15
Änderungen sind an Daten gebunden, nicht an Ganzzahlen:
2026-01-01 → Basisversion
2026-03-15 → `name` umbenannt in `display_name`
2026-06-01 → `legacy_field` entfernt
Server bindet unversionierte Anfragen an die Standardversion des Kontos.
Jede Version ist eine Transformationsschicht über dem kanonischen internen Modell.
Anti-Patterns
- Zu eifrig versionieren – die meisten Änderungen sind additiv und erfordern keinen Versionssprung; fügen Sie Felder frei hinzu
- Keine Auslauffrist – Auslauf ohne konkretes Enddatum führt zu ewig währenden Versionen
- Ganze Controller kopieren – verwenden Sie eine Transformations-/Adapterschicht, keine duplizierte Geschäftslogik pro Version
- Unbekannte Felder ignorieren – APIs sollten tolerante Leser sein; unbekannte Felder bei Eingabe ignorieren (Postels Gesetz)
- Breaking Changes in Nebenversionen – wenn Nutzer sich darauf verlassen haben, ist die Entfernung unabhängig von Ihrer Absicht ein Breaking Change
Qualitätscheckliste
- Additive Änderungen (neue Felder, neue Endpunkte) werden ohne Versionssprung ausgeliefert
- Breaking Changes erfordern eine Hauptversion mit 6+ Monaten Auslauffrist
- Sunset-Header (RFC 8594) ist bei auslaufenden Versionen gesetzt
- Link-Header verweist Nutzer auf die Nachfolgeversion
- Traffic pro Version wird überwacht, um den Migrationsfortschritt zu verfolgen
- OpenAPI-Spezifikation wird pro Version veröffentlicht, mit Diff-Werkzeugen (Optic/Bump.sh)
- Plan zur Benachrichtigung der Nutzer: Changelog, E-Mail, Dashboard-Warnung
- Versionsrouting erfolgt auf Gateway-Ebene, nicht im Anwendungscode
- Integrationstests validieren die Abwärtskompatibilität (Vertragstests)