GH GambleHub

Технологии и Инфраструктура → Версионирование 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. Версионирование ресурса/модели:

Один и тот же эндпоинт может возвращать разные представления: `fields=...` или `profile=lite|full`. Это дополнение, не замена версионности.

Рекомендация: для внешних интеграций — `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», а про процесс: явные правила эволюции, автоматические проверки совместимости, управляемые релизы и уважение к интеграциям. Введите понятную политику, автоматизируйте контроль и наблюдаемость — и изменения перестанут быть угрозой для продукта.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.