Compatibilitate Contract API
De ce compatibilitatea contractelor
Compatibilitatea contractului este capacitatea unui API de a evolua fără a rupe integrările existente. În sistemele în creștere, API-urile se schimbă mai des decât codul clientului; compatibilitatea vă permite să eliberați caracteristici iterativ, fără a aranja „mișcări mari”.
Ideea cheie: contractul este primar, modificările sunt efectuate în conformitate cu regulile de compatibilitate și sunt verificate automat.
Concepte de bază
Contract - specificație de interfață formală: resurse/metode/evenimente, scheme de date, coduri de eroare, limite, SLA-uri, cerințe de securitate.
Furnizor - Proprietarul API. Consumator - Client/Integrare.
- Înapoi: Noul furnizor lucrează cu consumatori vechi.
- Înainte: Vechiul furnizor lucrează cu noi consumatori (de obicei realizat de „cititori toleranți”).
- Full: se observă atât înapoi, cât și înainte (cea mai puternică opțiune).
- Aditivitate - adăugați elemente opționale fără a le rupe pe cele existente.
Politica de versioning
Versioning semantic (recomandat):- MAJOR - modificări de rupere (numai atunci când este lansată o nouă linie API: '/v2 ',' service. v2 ').
- MINOR - modificări aditive (noi câmpuri opționale/metode).
- PATCH - stabilește fără a schimba contractul.
- Politica de respingere: declararea elementelor învechite, fereastra de sprijin (apus de soare), avertismente în antete/metadate, planul de retragere.
Safe vs schimbari periculoase
Secure (de obicei compatibil înapoi)
Adăugați un câmp opțional la JSON/Protobuf/Avro.
Adăugați un nou punct final/metodă/eveniment.
Extinderea enumului cu noi valori dacă consumatorii tolerează valori necunoscute.
Ridicarea limitelor (de exemplu, "maxItems') fără a strânge minimul.
Adăugarea nullable cu implicite corecte.
Editare descriere/exemplu text.
Periculos (rupe compatibilitatea)
Redenumiți/ștergeți câmpurile, modificați tipul sau obligatoriu.
Status code/error semantics change (de exemplu, a fost '200', a devenit '204' sau '404').
Schimbarea formatului identificatorilor (UUID → int).
Strângerea validării (minime/modele mai stricte) fără versiune.
Schimbarea ordinii și structurii în fluxurile/evenimentele gRPC.
Reutilizați numerele de etichete în Protobuf pentru câmpuri noi.
Interoperabilitatea prin stilul de interacțiune
REST/HTTP + JSON Schema
Aditivitate: marcăm câmpurile noi ca fiind „opționale ”/„ nullable”.
Cititor tolerant la client: ignorați câmpurile necunoscute; nu se bazează pe ordine.
Versioning: major - pe drum ('/v2 ') sau în tipul media (' aplicare/vnd. exemplu. v2 + json ').
ETag/If-Match: pentru actualizări sigure fără curse.
Erori: formatul unic ('type', 'code', 'title', 'detail', 'trace _ id'), nu modificați valoarea' codului 'fără o valoare majoră.
Paginare: cursoarele sunt preferabile decalajului; adăugați câmpurile 'next _ cursor', nu modificați sensul celor existente.
gRPC/Protobuf
Numerotarea etichetelor este neschimbată. Etichetele șterse nu pot fi reutilizate.
Noile câmpuri sunt „opționale ”/„ repetate” cu implicite rezonabile pe server.
Nu modificați ordinea și mesajele obligatorii în streaming-RPC.
Stările de eroare sunt stabile ('INVALID _ ARGUMENT', 'FAILED _ PRECONDITION' etc.); semantică nouă → o nouă versiune a metodei/serviciului.
Event-driven (Kafka/NATS/Pulsar) + Schema Avro/JSON
Denumire evenimente: 'domeniu. acțiune. v {major} '.
Câmpurile noi sunt opționale; izolați miezul și îmbogățirea („.bogățit”).
Registrele schemei: reguli de compatibilitate (BACKWARD/FORWARD/FULL) pe temă/eveniment.
Extensia de enum este valabilă pentru cititorul tolerant din partea consumatorului.
Partiție/schimbare cheie ordine pentru agregate = modificări de rupere.
GraphQL
Adăugarea câmpurilor/tipurilor este sigură; șterge/redenumi - numai prin @ depreciate și fereastra de migrare.
Nu schimbați tipurile/non-nullable fără major.
Complexitatea/adâncimea controlului - limitele fac parte din contract.
Modele de evoluție durabilă
Aditiv-primul: Extindeți fără rupere.
Negocierea capacității: clienții raportează că acceptă (anteturi/parametri/acorduri), serverul se ajustează.
Limitele contractului: Fixați MGC (contractul minim de garanție) și extensii separate (modelul piramidei inverse).
Toleranță implicită: clienții ignoră valorile inutile și gestionează corect valorile necunoscute ale enum (rezervă).
Dual-write/Dual-emit: pentru modificări majore, eliberați „v1” și „v2” în paralel pentru un timp.
Anteturi/Evenimente Sunset: Notificați în avans atunci când versiunile sunt eliminate.
Guvernanță și automatizare
API Linters:- OpenAPI/Spectral: denumire, paginare, coduri de eroare, formate de câmp.
- Buf/Protobuf: interzicerea reutilizării etichetelor, notarea pachetelor.
- AsyncAPI/Schema Registry: compatibilitate schema de nivel CI.
- Catalog de contracte (SSOT): Registru centralizat schemă/versiune cu istoric difuz.
- API Guild: breaslă/comitet care adoptă reguli, șabloane și modificări de revizuire.
- Managementul schimbării: RFC/ADR, note de lansare, ghiduri de migrare.
Testarea compatibilității
Schema-diff în CI: bloc de rupere prăjituri (OpenAPI-diff, rupere Buf, compatibilitate SR).
Contracte bazate pe consumatori (CDC): Pact/Similar - Furnizor vs. contracte specifice consumatorilor.
Eșantioane de aur: interogări/răspunsuri de referință și evenimente pentru regresie.
E2E Canare: extinderea la cota de trafic/grupuri individuale consumator.
Haos/latență: Timeout/Retray check - O schimbare latență-SLO este considerată o schimbare de contract.
Migrații și depreciere
1. Declarați deprecierea: Marcați elementul, specificați termenul de apus și alternativa.
2. Mențineți perioada de compatibilitate: dual-write/dual-emit, poduri, adaptoare.
3. Colecta telemetrie: cine mai folosește vechiul?
4. Comunicare: corespondență, note de lansare, standuri de testare.
5. Îndepărtarea: după expirarea ferestrei - îndepărtarea cu o eliberare fixă.
Exemple de modificări
ODIHNA
A fost:json
{ "id":"p1", "status":"authorized" }
Devenit (aditiv, sigur):
json
{ "id":"p1", "status":"authorized", "risk_score": 0. 12 }
Clienții care ignoră câmpurile necunoscute nu se sparg.
Protobuf
proto message Payment {
string id = 1;
string status = 2; // don't change tag numbers optional double risk_score = 3; // additive
}
Eveniment
"plata. autorizat. v1 '(core) +' plată. îmbogățit. v1 '(îmbogățire). Consumatorii de căi critice citesc nucleul și nu depind de îmbogățire.
Antipatterns
Swagger-wash: există în mod oficial o specificație, dar comportamentul serviciului este în contradicție cu acesta.
Breaking by stealth: a schimbat tipul/starea/formatul fără o nouă versiune și fereastră de migrare.
Evenimente CDC brute ca un contract de achiziții publice: scurgeri de scheme DB, imposibilitatea evoluției.
Client dur: picături la câmpuri/valori necunoscute; absența unui cititor tolerant.
Reutilizarea etichetelor protobuf: corupere silențioasă a datelor.
Latența ca „non-contract”: p95 a fost prelungită în mod neașteptat - consumatorii se descompun în termene.
Lista de verificare a compatibilității (înainte de îmbinare)
- Modificările sunt aditive (sau versiunea majoră pregătită).
- Verificarea linterelor/diferențelor a trecut, regulile de compatibilitate sunt verzi.
- Erorile/codurile/stările nu au schimbat semantica.
- Enum extins fără a interzice valorile vechi; clienti - toleranti.
- Limitele MGC sunt neschimbate.
- Eșantioane actualizate/documentație/SDK.
- Pentru major - dual-write/dual-emit plan, apus de soare-data, comm-plan.
- Testele CDC/Golden/E2E trecut.
ÎNTREBĂRI FRECVENTE
Cum diferă înapoi de compatibilitatea înainte?
Înapoi - serverele noi nu sparg clienții vechi. Înainte - clienții noi nu se sparg pe servere vechi (prin cititor tolerant și implicite îngrijite).
Când faci „/v2 ”?
Când invarianții/semantica se schimbă, câmpurile/metodele sunt șterse, este necesar un nou model de securitate - este mai ușor și mai onest să începeți o nouă linie.
Poți trăi fără Schema Registry/linters?
Teoretic - da, practic - acestea sunt regresii frecvente și defecțiuni „ascunse”. Automatizarea dă roade.
Enum poate fi extins?
Da, dacă clienții gestionează corect valorile necunoscute (rezervă/ignoră). În caz contrar - major.
Total
Compatibilitatea contractului este reguli + disciplină + automatizare. Proiectați aditiv, modificările de rupere a versiunii, aplicați un cititor tolerant, verificați automat difs și CDC, depreciați planul. În acest fel, API-urile pot evolua rapid, iar integrările pot rămâne stabile.