Технології та Інфраструктура → Версіонування API
Версіонування API
1) Навіщо це потрібно
Версіонування - це керований спосіб змінювати контракти між сервісами і клієнтами без поломок. У продуктах з великим числом інтеграцій (платежі, KYC/AML, ігри, білінг, звітність) одночасно живуть «старі» і «нові» клієнти. Правильна політика версії:- знижує ризик інцидентів при релізах,
- дозволяє планово вводити поліпшення і безпеку,
- дає бізнесу передбачувані терміни міграцій партнерів.
2) Класифікація змін
PATCH (не ламають): виправлення без зміни контракту (додавання необов'язкових полів, фікси валідації).
MINOR (розширюючі): back-compatible розширення (нові ендпоінти, поля з default).
MAJOR (ламаючі): зміна структури, семантики або видалення полів/ендпоінтів.
Рекомендується SemVer'MAJOR. MINOR. PATCH'для артефактів (SDK/схеми), при цьому «зовнішній» номер API може бути спрощений (v1, v2).
3) Моделі версіонування REST
1. В URI:
`GET /v1/payments/{id}`
Плюси: прозоро, кешовано, легко маршрутизувати. Мінуси: дублювання документації, складніше тонко еволюціонувати.
2. У заголовках (content negotiation):
`Accept: application/vnd. company. payments. v2+json`
Плюси: гнучкість, відсутність «сміття» в URL, зручна еволюція медіатипу. Мінуси: складніше дебажити в браузері, потрібен дисциплінований клієнт.
3. У кастомному заголовку:
`X-API-Version: 2'( або'Api-Version: 2025-09-01`)
Плюси: просто на шлюзі. Мінуси: немає стандартності, обережно з кешем.
4. Версія-дата (date-based):
Добре для фінтех/звітності: передбачувані «розрізи» змін (наприклад, щоквартальні).
5. Версіонування ресурсу/моделі:
Рекомендація: для зовнішніх інтеграцій -'URI vN'+ Deprecation/Sunset заголовки; для внутрішніх - можна'Accept'або заголовок версії, якщо шлюз і платформа це підтримують.
4) GraphQL
Перевага - без глобальних версій. Еволюція через додавання полів/типів і деприкацію ('@deprecated (reason: "...")`).
Ламаючі зміни - тільки в «великих» вікнах (versioned schema namespace) з міграційним гайдом.
Слідкуйте за «n + 1» і за тим, щоб не змінювати meaning існуючих полів.
5) gRPC / Protobuf
Номери полів незмінні. Віддалені поля позначайте як «reserved».
Додавайте поля як optional з безпечними default.
Використовуйте buf breaking/lint для автоматичної перевірки сумісності.
Версіонуйте пакети/модулі: `package payments. v1;` → `payments. v2`.
6) Подієві API (EDA)
Схема події - такий же контракт. Зберігайте її в Schema Registry (Avro/JSON-Schema/Protobuf).
Топіки та версії: `payments. v1. authorized`, `payments. v2. authorized`.
Ламаючі зміни - новий тип події або новий топік.
Гарантії еволюції: backward-compatible для консумерів протягом періоду LTS.
7) Політика деприкації та EOL
Введіть прозорі правила:- Deprecation: мітки в changelog і в специфікаціях (OpenAPI/GraphQL SDL), заголовок
- `Deprecation: true'і коли можливо'Sunset: Tue, 31 Mar 2026 00:00:00 GMT`.
- Комунікації: email/портал партнера, webhooks-повідомлення, release notes.
- Терміни: MINOR - 3-6 місяців підтримки, MAJOR - 9-18 місяців (залежить від критичності).
- Тимчасові вікна: фіксуйте в «Політиці версіонування API».
8) Маршрутизація та релізи
API Gateway (Kong/Apigee/Nginx/Envoy): правила по префіксу '/v1/', по заголовку або медіатипу.
Приклад маршруту:
if ($http_accept ~ "vnd.company.payments.v2") { proxy_pass http://payments-v2; }
Canary/Blue-Green/Shadow: котіть нову версію на 1-5% трафіку, порівнюйте метрики і логи контрактних помилок.
Feature Flags: приховуємо поведінку, не змінюючи контракт.
Zero-downtime міграції: при MAJOR забезпечте подвійний запис/читання (dual-write/read) схеми даних.
9) Контракт-тестування та контроль сумісності
OpenAPI Diff (або swagger-diff) - перевірте, що MINOR/PATCH не ламають схеми.
Spectral лінтинг - стиль, обов'язкові метадані (версія, Deprecation).
Consumer-Driven Contracts (Pact) - гарантує, що провайдер не ламає клієнтів.
buf breaking для protobuf.
CI повинен падати при ламаючих змінах без підвищення MAJOR.
10) Документація та SDK
Версіонуйте спеки: `/docs/api/v1/openapi. json`, `/docs/api/v2/…`.
Генеруйте SDK за версіями (npm/maven/pypi) з SemVer і changelog.
Позначайте застарілі методи в SDK анотаціями/Deprecated.
11) Observability за версіями
Збирайте метрики окремо:- RPS/латентність/помилки на версію ('api _ version'лейбл).
- Карти використання ендпоінтів: хто ще на v1?
- Алерти: «> 10% 4xx due to contract mismatch», «старі клієнти> X% після T-дати».
12) Кешування та версії
Версія в дорозі покращує кешованість CDN.
При заголовних/медіатип версіях - уважно з Vary:- `Vary: Accept, X-API-Version`.
- Не змінюйте семантику відповіді в MINOR так, щоб ламати кеш-ключі.
13) Безпека
Не шифруйте і не вшивайте версію в JWT - версію визначає запит, а не токен.
Не розкривайте внутрішні номери збірок. У зовнішніх повідомленнях використовуйте «v1/v2».
При MAJOR перегляньте валідацію, ліміти, маскування PII.
14) Міграції та авто-помічники
Публікуйте «Migration Guide v1 → v2»: таблицю відповідностей полів, приклади запитів/відповідей, edge-кейси.
Пропонуєте лінтери для клієнтів (CLI), які підсвітять застарілі поля.
Для великих партнерів - sandbox з двома версіями і тест-датасетом.
15) Анти-патерни
«Вічний v1»: відсутність дедлайнів і метрик використання.
Приховані ламаючі зміни в MINOR/PATCH.
«Версія в query string» ('? v = 2') - ламає кеш і читаність.
«Один ендпоінт - сто значень прапора»: важко тестувати/документувати.
16) Чек-лист впровадження
1. Обрана модель (URI/Accept/Header) для зовнішніх і внутрішніх клієнтів.
2. SemVer для специфікацій і SDK, автоматичний breaking-check в CI.
3. Deprecation/Sunset політика і шаблони комунікацій.
4. Gateway-маршрутизація + канарки, дашборди за версіями.
5. CDC/Contract tests на критичні інтеграції (платежі, KYC, звітність).
6. Документація/SDK/міграційний гід опубліковані одночасно з релізом.
7. План EOL з датами і відповідальними.
17) Приклади
17. 1 REST (URI + заголовки)
Запит:
GET /v2/withdrawals/12345
Accept: application/json
Idempotency-Key: 4a1c-…-9f
Відповідь:
json
{
"id": "12345",
"status": "PENDING_REVIEW",
"amount": {"value": "100.00", "currency": "EUR"},
"limits": {"daily": "500.00"},
"created_at": "2025-10-02T10:00:00Z",
"links": [{"rel": "cancel", "href": "/v2/withdrawals/12345/cancel", "method": "POST"}]
}
Заголовки деприкації (на v1):
Deprecation: true
Sunset: Tue, 31 Mar 2026 00:00:00 GMT
Link: </v2/docs>; rel="successor-version"
17. 2 Content Negotiation (медіатип)
GET /payments/987
Accept: application/vnd.company.payments.v2+json
Vary: Accept
17. 3 GraphQL (деприкація поля)
graphql type Payment {
id: ID!
amount: Money!
status: PaymentStatus!
method: PaymentMethod!
legacyCode: String @deprecated(reason: "Use field `method`")
}
17. 4 gRPC (protobuf)
proto package payments.v2;
message Withdrawal {
string id = 1;
Money amount = 2;
string status = 3; // previously enum, now string with documented values reserved 4; // legacy field removed in v1 -> v2
}
17. 5 Подієва модель
Топіки:- `wallet. v1. balance. updated`
- `wallet. v2. balance. changed'( нова подія з розширеною схемою)
Схеми зберігаються в Registry, продюсер не публікує події зі схемою, що порушує сумісність.
18) Контекст iGaming/фінтех (практика)
Платежі: введення v2 для нових PSP, де'status '/' decline _ reason'розширені; на шлюзі маппінг v1 → v2 для звітності.
KYC: MINOR додає поле'pep _ screening', клієнти v1 ігнорують, v2 - вимагає.
Відповідальні ігри/ліміти: MAJOR змінює модель лімітів (добові/тижневі). Подвійний експорт у звітність до EOL v1.
Звітність регуляторам: фіксовані версії-дати: `reporting-2025-01`.
19) Міні-політика (приклад для wiki)
Модель: для зовнішніх API -'URI/vN/'; для внутрішніх -'Accept: …vN+json` или `X-API-Version: N`.
SemVer: специфікації і SDK публікуються як'N. minor. patch`. MAJOR вимагає RFC/ADR.
Сумісність: MINOR/PATCH - без ламаючих змін. Ламаюче → тільки через MAJOR.
Deprecation/EOL: оголошення за ≥90 днів; Sunset-дата в заголовках; LTS-гілка для критичних клієнтів.
Контроль: OpenAPI diff/buf breaking в CI, CDC для ключових інтеграцій.
Observability: метрики/логи з лейблом'api _ version'.
Релізи: canary 5% ≥ 24год, потім поетапно до 100% при зелених метриках.
Підсумок
Версіонування - це не про «/v2 в URL », а про процес: явні правила еволюції, автоматичні перевірки сумісності, керовані релізи і повага до інтеграцій. Введіть зрозумілу політику, автоматизуйте контроль і спостережуваність - і зміни перестануть бути загрозою для продукту.