API-Versionierung und vertragliche Kompatibilität
TL; DR
Kompatibilität ist Disziplin, kein Glück. Halten Sie klare Versionsrichtlinien (SemVer), Änderungsmathematik (was „bricht“, was nicht), Vertragstests, Schaltungsregister und Sunset-Verfahren. Für Geld und Compliance gibt es einen strengen REST/gRPC mit vN, für UI-Aggregationen einen evolutionären GraphQL mit'@ deprecated'. Immer: Kanarienverkehr, Abwärtskompatibilität ≥ ein Releasezyklus, Migrationsgades, Feldnutzungstelemetrie.
1) Grundbegriffe und Ziele
Backwards-kompatible (BC): Alte Clients passen zum neuen Server.
Forwards-kompatibel (FC): Neue Clients passen zum alten Server (eingeschränkt).
Drahtkompatibilität: Das Format auf dem „Draht“ bricht nicht (besonders wichtig für gRPC/Protobuf).
SemVer: `MAJOR. MINOR. PATCH'- Brechen Sie den Vertrag → erhöhen Sie MAJOR.
Das Ziel: Bruchveränderungen minimieren und planbare Migrationsfenster ermöglichen.
2) Matrix der Veränderung: Was möglich ist und was nicht
3) Richtlinien für verschiedene API-Stile
3. 1 REST
Version im URI ('/v1/...') oder in der Domäne ('api-v1.'). Die Header-Version ist nur für interne Fälle.
Hinzufügen, nicht löschen: Neue Felder - ok, alte - im Schema als' deprecated 'markieren und mindestens eine Schleife belassen.
Status/Fehler: Ändern Sie nicht die Codes und die Struktur von 'error. code/error. message/error. details`.
Die Idempotenz ist unverändert: Verwandeln Sie den sicheren 'POST' mit dem 'Idempotency-Key' nicht in eine „verhaltensanfällige“ Herausforderung.
3. 2 gRPC / Protobuf
Feldnummern sind heilig: Verwenden Sie keine gelöschten Nummern, markieren Sie sie als „reserviert“.
Nur Hinzufügen neuer optionaler/Repit-Felder; „hart obligatorisch“ - durch Validierung, nicht 'erforderlich'.
Versionspakete: 'payments. v1`, `payments. v2`.
Kompatibilität der Dienste: neue RPCs → eine neue Methode; Das Verhalten der Alten ändert sich nicht.
proto message Payout {
reserved 4 ;//field deleted, number reserved string id = 1;
string currency = 2;
int64 amount_minor = 3;
// v2: optional string comment = 5;
}
3. 3 GraphQL
Evolution ohne v2: Felder/Typen hinzufügen; Löschen - über'@ deprecated (reason) 'mit Fensterankündigung.
Persisted Queries: Verwenden Sie für öffentliche Kunden eine weiße Liste von Anfragen - es ist einfacher, die Kompatibilität zu kontrollieren.
Field-level authZ und Telemetrie: Wissen Sie, welche Felder tatsächlich verwendet werden, bevor Sie sie löschen.
graphql type Payout {
id: ID!
amountMinor: Long!
currency: String!
comment: String @deprecated(reason: "Use note")
note: String
}
3. 4 Webhooks
Version im Transit ('/webhooks/v1/payments') und fester Event-Umschlag ('event _ id', 'type', 'ts', 'data').
Signaturen/NMAS unverändert beibehalten; neue Algorithmen - als Option mit Flagge.
Erweiterungen - nur durch die neuen Felder 'Daten' und 'Köpfe' - ohne die alten zu löschen.
4) API Gateway und Versionsrouting
Rules-basiertes Routing: durch Präfix '/v1', durch Header 'X-Api-Version', durch Domain.
Shadow/Canary: Reflektieren Sie einen Teil des Produktionsverkehrs auf die neue Version „im Schatten“, vergleichen Sie die Antworten.
Rate/Quotas per-version: Schützt alte Kunden während der Migration.
- 'Sonnenuntergang:
' - Datum, an dem die Version abgeschaltet wurde - 'Deprecation: true' - die Version ist veraltet
- `Link:
; rel = „deprecation“'- auf dem Migrations-Changelog/Hyde
nginx location ~ ^/v2/ {
proxy_pass http://api_v2;
}
location ~ ^/v1/ {
add_header Deprecation "true";
add_header Sunset "Thu, 01 May 2026 00:00:00 GMT";
proxy_pass http://api_v1;
}
5) Scheme-Register und Verträge
OpenAPI / JSON Schema для REST; Protobuf descriptors для gRPC; SDL registry для GraphQL.
CI-Checks: linters + „breaking-changes check“ bei PR.
Consumer-Driven Contracts (CDC): Verbrauchertests (Pact/analog) - Schutz vor unauffälligem Bruch.
Changelog: maschinenlesbar (z.B. 'CHANGELOG. md'+ release notes im Register).
6) Die Entwicklung der Felder: praktische Regeln
ID/Schlüssel: Ändern Sie das Format (UUID↔int) nicht ohne ein neues'_ v2 '-Feld und eine Übergangszeit.
Zeit/Währung: Halten Sie UTC ISO-8601/epoch und amount_minor + Währung; Ändern Sie nicht den Maßstab (Cent/Cent).
Enum: Werte hinzufügen - ok; Ändern Sie nicht die Bedeutung der alten. Für REST - Geben Sie String-Werte, nicht ints.
Pagination: cursor-based stabiler; Ändern Sie nicht die Semantik des Cursors.
7) Enteignung und „Sunset“ -Verfahren
1. Ankündigung (T-90/60): Änderung, Versand an Partner, Überschriften „Deprecation/Sunset“.
2. Doppelte Periode: V1 und V2 arbeiten parallel; V1 ist mit Warnhinweisen in den Antworten/Protokollen versehen.
3. Nutzungstelemetrie: Wer ruft noch V1? Punktkontakte.
4. Einfrieren von V1: nur Bugfixes/kein Fich.
5. Ausschalten (Sunset): 410 Gone oder Blockseite mit Migrationsanweisung.
8) Releases ohne Schmerzen: Layoutstrategien
Blau/Grün oder Gewichtete Route: 1-5-25-50-100% des Verkehrs.
Kompatibilitätsfenster: mindestens 1-2 kleinere Versionen, häufiger 6-12 Monate für externe APIs.
Feature Flags: um neue Felder/Zweige der Logik einzuschließen, ohne die Version zu ändern.
Read/Write-Split: Fügen Sie zuerst Unterstützung für das Lesen eines neuen Feldes hinzu und beginnen Sie dann, es zu schreiben.
9) Kompatibilitätsprüfung (Praxispaket)
Golden-Tests auf die Antworten der alten Versionen.
Diff-Tests von Schaltungen: Verbot von Breaking in CI.
Replay Produktion Tracks auf Staging für V2 (Schatten).
Back/Forward-Szenarien: neuer Client auf dem alten Server und umgekehrt (wo FC zulässig ist).
Vertragstests von Webhooks: Überprüfung von Signatur, Format, Zeit.
10) Metriken und SLO des Versionierungsprozesses
% der Kunden auf der letzten MINOR (Ziel ≥ 80% vor Sunset).
Kompatibilitäts-/Nichtverfügbarkeitsfehler pro Release (Ziel ist 0).
Anteil der Aufrufe der veralteten Version (abnehmend zu Sunset).
Zeitpunkt der Client-Migration (Median/p95).
Latenz/Regression delta zwischen den Versionen (nicht schlechter als die Basis).
11) Beispiele für Artefakte
OpenAPI (Fragment, Feldentzug):yaml components:
schemas:
Payout:
type: object properties:
id: { type: string, format: uuid }
amount_minor: { type: integer }
currency: { type: string }
comment:
type: string deprecated: true description: "Use note"
note: { type: string }
Protobuf (reserviert und v2 Paket):
proto syntax = "proto3";
package payouts. v1;
message Payout { reserved 5; string id=1; int64 amount_minor=2; string currency=3; }
GraphQL (Deprivation):
graphql type Query { payout(id: ID!): Payout }
12) Versionierung benachbarter Kanäle
SDK/CLI: SemVer + Abhängigkeit von API-Version, Kompatibilität in README festgelegt.
Events/Streams (WS/Kafka): Version in 'envelope. version`; neue Attribute - optional; dedup und Zusammenfassung arbeiten auf die gleiche Weise zwischen den Versionen.
Reporting/CSV: Version im Dateinamen/Cap; Spalten auf der rechten Seite hinzufügen; Ändern Sie nicht die Reihenfolge/Typen.
13) Governance und Rollen
Vertragsinhaber (Domain Owner), Steward API (Regeln und Linter), Release Manager (Sunset/Kommunikation).
RFC-Prozess für Breaking Change: Business Case, Migrationsplan, Artefakte, Termine.
Einheitliches API-Verzeichnis: wo Diagramme, Versionen, Sunset-Kalender, Kontakt sichtbar sind.
14) Anti-Muster
„Stille“ Brüche: Status/Fehler/Feldtyp ohne Version ändern.
Überverwendung von Protobuf-Nummern - zerstört Replikate und alte Kunden.
GraphQL ohne Feldverwendung Telemetrie - Entfernen „Berührung“.
Global v2 ist alles Megamigration statt Punkteentwicklung.
Die Version im query-Parameter für die öffentliche API ist ein nicht offensichtliches und anfälliges Schema.
Es gibt keine Migrationszüge und -beispiele - die Partner stocken, Fristen brechen.
15) Check-Liste der Veröffentlichung der neuen Version
- Schema aktualisiert (OpenAPI/Protobuf/SDL), Linter und Breaking-Checks bestanden.
- Integrations- und Vertragstests (CDC) hinzugefügt.
- SDK/Codebeispiel/Migrationshyde und Changelog sind fertig.
- Enthalten sind 'Deprecation/Sunset' (für die alte Version) + die Seite „How to migrate“.
- Canary/Shadow Plan, Alerts und Dashboards vergleichen Metriken.
- Die Abwärtskompatibilität wird für den vereinbarten Zeitraum beibehalten.
- Der Rollback-Plan (Rollback) und die Risikomatrix sind aufeinander abgestimmt.
Zusammenfassung
Eine stabile API ist ein Prozess, kein „ein für alle Mal“. Leben Sie nach den Regeln: SemVer + add-only evolution + scheme register + contract tests + Sunset-procedures. Trennen Sie Stile (REST/gRPC/GraphQL) und deren Richtlinien, leiten Sie Versionen an die Gateway-API weiter, rollen Sie Kanarienvögel aus, messen Sie den Effekt. So vermeiden Sie „brechende Überraschungen“, beschleunigen die Partner-Integrationen und bleiben berechenbar für geld- und compliance-kritische Domains.