Weryfikacja API i kompatybilność kontraktu
TL; DR
Kompatybilność to dyscyplina, nie szczęście. Zachowaj jasną politykę wersji (SemVer), zmień matematykę (co „łamie”, co nie), testy kontraktowe, rejestry schematów i procedury Sunset. Dla pieniędzy i zgodności - ścisły REST/gRPC z vN, dla agregacji UI - ewolucyjny GraphQL z '@ deprecated'. Zawsze: ruch kanaryjski, kompatybilność wsteczna ≥ jeden cykl uwalniania, przewodniki migracji, telemetria polowa.
1) Podstawowe koncepcje i cele
Kompatybilność wsteczna (BC): stare klienci są odpowiednie dla nowego serwera.
Kompatybilność Forwards (FC): nowi klienci nadają się do starego serwera (ograniczona).
Kompatybilność drutu: format na „drucie” nie pęka (szczególnie ważny dla gRPC/Protobuf).
SemVer: "MAJOR. DROBNE. PATCH '- złamać kontrakt → podnieść MAJOR.
Celem jest zminimalizowanie zakłócających zmian i zapewnienie przewidywalnych okien migracji.
2) Zmień matrycę: Co możesz i nie możesz
3) Polityka dla różnych stylów API
3. 1 ODPOCZYNEK
Wersja w URI ('/v1/... „) lub domeny (” api-v1. '). Wersja nagłówka - tylko dla spraw wewnętrznych.
Dodaj, nie usuwaj: nowe pola - ok, stare - oznaczają jako 'zdeprecowane' na wykresie i pozostawiają na co najmniej jeden cykl.
Statusy/błędy: nie zmieniaj kodów i błędu struktury '. kod/błąd. komunikat/błąd. szczegóły ".
Idempotencja jest niezmieniona: nie zmieniaj bezpiecznego 'POST' z 'Idempotence-Key' na 'behawioralnie inne' wyzwanie.
3. 2 gRPC/Protobuf
Numery pola są święte: nie używać ponownie usuniętych numerów, oznaczać jako „zastrzeżone”.
Dodawanie tylko nowych pól opcjonalnych/repitów; „ciężko obowiązkowe” - przez walidację, nie „zapytane”.
Pakiety wersji: 'płatności. v1 „,” płatności. v2 ".
Kompatybilność usługi: nowe RPC → nowa metoda; nie zmieniamy zachowania starego.
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
Ewolucja bez v2: dodać pola/typy; deletion - poprzez '@ deprecated (reason)' wraz z ogłoszeniem okna.
Ciągłe pytania: Dla klientów publicznych użyj białej listy zapytań - łatwiej jest kontrolować kompatybilność.
Pole-poziom authZ i telemetria: wiedzieć, które pola są faktycznie używane przed usunięciem.
graphql type Payout {
id: ID!
amountMinor: Long!
currency: String!
comment: String @deprecated(reason: "Use note")
note: String
}
3. 4 haki internetowe
Wersja w ścieżce ('/webhooks/v1/payments ') i kopercie zdarzeń stałych (' event _ id', 'type', 'ts',' data ').
Przechowywanie podpisów/NMAS bez zmian; nowe algorytmy - jako opcja z flagą.
Rozszerzenia - tylko przez dane nowych pól. "i" nagłówki "- bez usuwania starych.
4) Brama API i routing wersji
Routing oparty na zasadach: przez prefiks '/v1 ', nagłówek' X-Api-Version ', przez domenę.
Shadow/Canary: Odzwierciedl niektóre ruch produkcyjny na nowej wersji „w cieniu”, porównaj odpowiedzi.
Stawka/kwoty na wersję: Chroni starszych klientów podczas migracji.
- „Zachód słońca:
” - data wyłączenia wersji - „Deprecacja: prawda” - wersja staje się przestarzała
- "Link:
; rel = „deprecation” - on changelog/migration guide
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) Rejestry systemów i umowy
OpenAPI/JSON Schema дла REST; Protobuf descriptors дла gRPC; Rejestr SDL мла GraphQL.
CI checks: linters + „breaking-change check” w PR.
Umowy konsumenckie (CDC): Testy konsumenckie (pakt/analogowy) - ochrona przed niepozornymi przerwami.
Changelog: czytelny dla maszyny (na przykład "CHANGELOG. md' + uwagi do wydania w rejestrze).
6) Ewolucja pól: zasady kciuka
ID/klucze: nie zmieniaj formatu (UUID na int) bez nowego pola '_ v2' i okresu przejściowego.
Czas/waluta: zachować ISO-8601/epoch UTC i amount_minor + walutę; nie skalować (grosze/centy).
Enum: dodać wartości - ok; nie zmieniaj znaczenia starych. Dla REST podaj wartości strun, a nie ints.
Paginacja: bardziej stabilna na podstawie kursora; nie zmieniać semantyki kursora.
7) Procedura wyczerpywania i „Zachód słońca”
1. Ogłoszenie (T-90/60): changelog, mailing to partners, nagłówki „Deprecation/Sunset”.
2. Duplikat: V1 i V2 działają równolegle; V1 jest wyposażony w ostrzeżenia w odpowiedziach/dziennikach.
3. Telemetria użycia: Kto jeszcze dzwoni do V1? kontakty punktowe.
4. Zamrażanie V1: tylko poprawki błędów/brak funkcji.
5. Sunset-410 Zniknęła lub strona bloku instrukcji migracji.
8) Uwolnienia wolne od bólu: nioski strategii
Niebieski/zielony lub ważony routing: 1-5-25-50-100% ruchu.
Okno kompatybilności: co najmniej 1-2 drobne wydania, częściej 6-12 miesięcy dla zewnętrznych API.
Flagi funkcji, aby zawierać nowe pola/gałęzie logiczne bez aktualizacji.
Read/Write-split: najpierw dodaj wsparcie do odczytu nowego pola, a następnie zacznij go pisać.
9) Testy interoperacyjności (zestaw ćwiczeń)
Złote testy na odpowiedzi starszych wersji.
Badania różnicowe obwodów: brak przerwy w CI.
Powtórka produkcji działa na postoju dla V2 (cień).
Skrypty Back/Forward: nowy klient na starym serwerze i odwrotnie (gdzie FC jest ważne).
Testy kontraktowe haków webowych: weryfikacja podpisu, formatu, czasu.
10) Metryki i SLO procesu wersioning
% klientów na ostatnim MINOR (cel ≥ 80% przed zachodem słońca).
Błędy kompatybilności/niedostępności na zwolnienie (cel 0).
Udział połączeń spuścizny (zmniejsza się do zachodu słońca).
Czas migracji klienta (mediana/p95).
Delta opóźnienia/regresji między wersjami (nie gorzej niż podstawowe).
11) Przykłady artefaktów
OpenAPI (fragment, brak pola):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 (opakowanie zastrzeżone i v2):
proto syntax = "proto3";
package payouts. v1;
message Payout { reserved 5; string id=1; int64 amount_minor=2; string currency=3; }
GraphQL (wyczerpanie):
graphql type Query { payout(id: ID!): Payout }
12) Wersioning sąsiednich kanałów
SDK/CLI: zależność od wersji SemVer + API, zgodność przewidziana w README.
Wydarzenia/strumienie (WS/Kafka): wersja w 'envelope. wersja "; nowe atrybuty - opcjonalne; dedup i wznawia pracę w ten sam sposób między wersjami.
Raportowanie/CSV: wersja w nazwie pliku/nagłówku; Dodaj kolumny do prawej nie zmieniaj kolejności/typów.
13) Zarządzanie i role
Właściciel kontraktu (właściciel domeny), Steward API (zasady i lintery), Menedżer zwolnień (Sunset/communications).
Proces RFC do przełamywania zmian: uzasadnienie biznesowe, plan migracji, artefakty, daty.
Jednolity katalog API: gdzie widoczne są schematy, wersje, kalendarz zachód słońca, kontakt.
14) Anty-wzory
„Ciche” przerwy: zmienić status/błąd/typ pola bez wersji.
Ponowne wykorzystanie numerów protobufu - niszczy powtórki i starych klientów.
GraphQL bez telemetrii polowej - usuwanie dotyku.
Globalna suma v2 - megamigracja zamiast ewolucji punktowej.
Wersja w parametrze zapytania dla publicznego interfejsu API jest schematem niewidocznym i podatnym na zagrożenia.
Nie ma przewodników migracji i przykładów - partnerzy stall, terminy są zakłócane.
15) Wydanie listy kontrolnej nowej wersji
- Zaktualizowany schemat (OpenAPI/Protobuf/SDL), lintery i sprawdzanie łamania przeszedł.
- Dodano testy integracyjne i kontraktowe (CDC).
- SDK/kod próbki/przewodnik migracji i Changelog gotowy.
- Deprecation/Sunset enabled (stara wersja) + Jak migrować stronę.
- Plan Canary/Shadow, alerty i deski rozdzielcze porównujące mierniki.
- Zgodność wsteczna jest utrzymywana przez uzgodniony okres.
- Uzgodniono plan wycofania i macierz ryzyka.
Podsumowanie
Stabilny API to proces, a nie "raz na zawsze. "Żyj zgodnie z zasadami: SemVer + ewolucja + rejestr obwodów + testy kontraktowe + Procedury wygaśnięcia. Oddzielne style (REST/gRPC/GraphQL) i ich zasady, wersje trasy do interfejsu API Gateway, roll out canaries, zmierzyć efekt. Dzięki temu unikniesz „przełamywania niespodzianek”, przyspieszysz integrację partnerów i utrzymasz przewidywalność dla domen pieniężnych i krytycznych dla zgodności.