Versionarea API și compatibilitatea contractelor
TL; DR
Compatibilitatea este disciplina, nu norocul. Păstrați o politică de versiune clară (SemVer), schimbați matematica (ce „pauze”, ce nu), testele contractuale, registrele schemelor și procedurile Sunset. Pentru bani și conformitate - REST/gRPC strict cu vN, pentru agregări UI - GraphQL evolutiv cu „@ depreciate”. Întotdeauna: trafic canar, compatibilitate înapoi ≥ un ciclu de eliberare, ghiduri de migrare, telemetrie câmp.
1) Concepte și obiective de bază
Compatibil cu spatele (BC): clienții vechi sunt potriviți pentru noul server.
Forwards-compatibil (FC): clienții noi sunt potriviți pentru vechiul server (limitat).
Compatibilitate sârmă: formatul de pe „sârmă” nu se rupe (în special important pentru gRPC/Protobuf).
SemVer: "MAJOR. MINOR. PATCH "- rupe contractul → ridica MAJOR.
Scopul este de a minimiza schimbările perturbatoare și de a oferi ferestre de migrare previzibile.
2) Schimbați matricea: Ce puteți și ce nu puteți
3) Politici pentru diferite stiluri API
3. 1 REST
Versiune în URI ('/v1/... „) sau domeniu (” api-v1. '). Versiunea antet - numai pentru cazurile interne.
Adăugați, nu ștergeți: câmpuri noi - ok, vechi - marcați ca „depreciate” în diagramă și lăsați cel puțin un ciclu.
Stări/erori: nu modificați codurile și structura 'error. cod/eroare. mesaj/eroare. detalii ".
Idempotența este neschimbată: nu transformați un „POST” sigur cu „Idempotency-Key” într-o provocare „diferită din punct de vedere comportamental”.
3. 2 gRPC/Protobuf
Numerele de câmp sunt sacre: nu reutilizați numerele șterse, marcați ca „rezervate”.
Doar adăugarea de noi câmpuri opționale/repit; "greu obligatoriu" - prin validare, nu "required'.
Pachete versiune: "plăți. v1 ', "plăţi. v2 '.
Compatibilitatea serviciilor: noile RPC-uri → o nouă metodă; noi nu schimbăm comportamentul vechiului.
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
Evoluție fără v2: adăugați câmpuri/tipuri; ștergere - prin „@ depreciat (motiv)” cu anunțarea ferestrei.
Interogări persistente: Pentru clienții publici, utilizați o listă albă de întrebări - este mai ușor de controlat compatibilitatea.
Field-level authZ și telemetrie: știu ce câmpuri sunt de fapt utilizate înainte de ștergere.
graphql type Payout {
id: ID!
amountMinor: Long!
currency: String!
comment: String @deprecated(reason: "Use note")
note: String
}
3. 4 Cârlige Web
Versiune în cale ('/webhooks/v1/payments') și plic eveniment fix ('event _ id',' type ',' ts', 'data').
Păstrați neschimbate semnăturile/NMAS; noi algoritmi - ca o opțiune cu un steag.
Extensii - numai prin datele noilor câmpuri. "şi" anteturi "- fără a le şterge pe cele vechi.
4) Gateway API și versiunea de rutare
Rutare bazată pe reguli: prin prefix „/v1 ”, prin antetul„ X-Api-Version ”, pe domeniu.
Shadow/Canary: Reflectați o parte din traficul de producție pe noua versiune „în umbre”, comparați răspunsurile.
Rate/Cote pe versiune: Protejează clienții mai în vârstă în timpul migrării.
- 'Apus de soare:
' - data închiderii versiunii - „Depreciere: adevărat” - versiunea devine caducă
- 'Link:
; rel = "depreciere" "- pe changelog/ghid de migrare
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) Registre de scheme și contracte
OpenAPI/JSON Schema для REST; Protobuf descriptori для gRPC; Registry SDL для GraphQL.
CI verifică: linters + „breaking-changes check” în PR.
Contracte bazate pe consumatori (CDC): Teste pentru consumatori (pact/analog) - protecție împotriva pauzelor inconsecvente.
Changelog: mașină de citit (de exemplu, "CHANGELOG. md '+ note de lansare în registru).
6) Evoluția câmpurilor: reguli de degetul mare
ID/chei: nu modificați formatul (UUID↔int) fără un nou câmp '_ v2' și o perioadă de tranziție.
Timp/valută: păstrați ISO-8601/epoch UTC și moneda amount_minor +; nu scalați (bănuți/cenți).
Enum: adăugați valori - ok; nu schimba sensul celor vechi. Pentru REST, dați valori de șir, nu ints.
Paginare: pe bază de cursor mai stabil; nu schimba semantica cursorului.
7) Epuizarea și procedura „Apus de soare”
1. Anunț (T-90/60): changelog, corespondență către parteneri, titlurile 'Deprecation/Sunset'.
2. Perioada duplicat: V1 și V2 funcționează în paralel; V1 este echipat cu avertismente în răspunsuri/jurnale.
3. Telemetrie de utilizare: Cine altcineva apelează V1? contacte punct.
4. Congelare V1: numai bug fixat/nici o caracteristică.
5. Sunset-410 Gone sau pagina de instrucțiuni de migrare.
8) Eliberări fără durere: strategii de stabilire
Rutare albastră/verde sau ponderată: 1-5-25-50-100% trafic.
Fereastra de compatibilitate: cel puțin 1-2 versiuni minore, mai des 6-12 luni pentru API-uri externe.
Caracteristică Steaguri pentru a include noi câmpuri logice/ramuri fără upgrade.
Citiți/Scrieți-împărțiți: adăugați mai întâi suport pentru citirea unui nou câmp, apoi începeți să-l scrieți.
9) Testarea interoperabilității (suită de practică)
Teste de aur pentru răspunsuri din versiuni mai vechi.
Teste diff de circuite: nici o rupere în CI.
Producția de replay rulează în stadiul pentru V2 (umbră).
Back/Forward scripturi: client nou pe serverul vechi și invers (în cazul în care FC este valabil).
Testele contractuale ale cârligelor web: verificarea semnăturii, formatului, timpului.
10) Metrica și SLO-urile procesului de versionare
% dintre clienții de pe ultimul MINOR (țintă ≥ 80% înainte de apus).
Erori de compatibilitate/indisponibilitate per versiune (țintă 0).
Ponderea apelurilor moștenite (în scădere la apus).
Timpul de migrare al clientului (mediană/p95).
Latență/regresie delta între versiuni (nu mai rău decât de bază).
11) Exemple de artefacte
OpenAPI (fragment, depriciere câmp):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 (pachet rezervat și v2):
proto syntax = "proto3";
package payouts. v1;
message Payout { reserved 5; string id=1; int64 amount_minor=2; string currency=3; }
GraficQL (epuizare):
graphql type Query { payout(id: ID!): Payout }
12) Versionarea canalelor adiacente
SDK/CLI: dependența versiunii SemVer + API, compatibilitatea stipulată în README.
Evenimente/fluxuri (WS/Kafka): versiunea in 'envelope. versiunea "; atribute noi - opțional; dedup și CV-uri funcționează la fel între versiuni.
Raportare/CSV: versiune în nume de fișier/antet; Adăugați coloane la dreapta nu modificați ordinea/tipurile.
13) Guvernanță și roluri
Proprietar de contract (proprietar de domeniu), API Steward (reguli și lintere), Release Manager (Apus de soare/comunicații).
Proces RFC pentru modificări de rupere: justificare de afaceri, plan de migrare, artefacte, date.
Directorul API unificat: unde sunt vizibile diagramele, versiunile, calendarul Sunset, contactul.
14) Anti-modele
Pauzele „silențioase”: modificați tipul de stare/eroare/câmp fără o versiune.
Reutilizarea numerelor protobuf - distruge reluarea și clienții vechi.
GraphQL fără telemetrie de câmp - îndepărtarea tactilă.
Global v2 total - megamigrație în loc de evoluția punctelor.
Versiunea în parametrul de interogare pentru API-ul public este o schemă non-evidentă și vulnerabilă.
Nu există ghiduri și exemple de migrație - partenerii trag de timp, termenele sunt perturbate.
15) Check-list eliberarea noii versiuni
- Schema actualizată (OpenAPI/Protobuf/SDL), linterele și verificările de rupere au trecut.
- Integrarea și testele contractuale (CDC) adăugate.
- SDK/cod de probă/ghid de migrare și Changelog gata.
- Depreciere/Sunset activat (versiunea veche) + Cum de a migra pagina.
- Planul Canare/Umbre, alerte și tablouri de bord care compară valorile.
- Compatibilitatea înapoi este menținută pentru o perioadă convenită.
- Planul rollback și matricea de risc a fost de acord.
Rezumat
Un API stabil este un proces, nu "o dată pentru totdeauna. "Live by the rules: SemVer + add-only evolution + circuit register + test de contract + proceduri Sunset. Stiluri separate (REST/gRPC/GraphQL) și politicile lor, versiuni de traseu la API Gateway, rula canare, măsura efectul. În acest fel veți evita „spargerea surprizelor”, accelerarea integrării partenerilor și menținerea predictibilității pentru domeniile monetare și critice de conformitate.