GH GambleHub

Стратегии версионирования API

Зачем нужно версионирование

API меняется быстрее, чем клиенты. Версионирование позволяет выпускать фичи и править ошибки без поломок интеграций, задает ритуал изменений и делает эволюцию предсказуемой. Ключ: аддитивные изменения по умолчанию, majors — только для ломок, автоматические проверки совместимости и продуманная политика sunset.


Базовые принципы

1. Additive-first: новые опциональные поля/методы/события — ок; удаления и изменение смысла — мажор.
2. MGC (минимальный гарантийный контракт) стабилен; обогащения — через capabilities/`?include=`.
3. Tolerant reader: клиенты игнорируют неизвестные поля и корректно переживают расширения enum.
4. Semantic Versioning: `MAJOR.MINOR.PATCH` для артефактов, SDK и событий.
5. Automate: schema-diff, линтеры и CDC-тесты блокируют breaking-изменения.


Где хранить версию (механики адресации)

REST/HTTP

URI-версия: `/v1/orders` → просто маршрутизировать, удобно в шлюзах. Минус — «заслоняет» эволюцию представлений.
Медиатип/заголовок: `Accept: application/vnd.example.orders.v1+json` — точное управление форматом; сложнее дебажить.
Query-версия: `?api-version=1` — удобно для A/B, но легко потерять в кешах/логах.
Рекомендация: URI для major-линий + feature/capability flags и контент-негацияция для минорных расширений.

gRPC / Protobuf

Пакеты/сервисы: `package payments.v1; service PaymentsV1;` — явные линии.
Нумерация тегов неизменна; удаленные теги не переиспользовать.
Новые поля — `optional`; breaking → новый `.v2`.

GraphQL

Схема без явных major в URL. Эволюция через @deprecated и окна миграции; «настоящий» major — новая эндпоинт-схема.
Контролируйте complexity/depth — это часть контракта.

Event-driven (Kafka/NATS/Pulsar)

Имя события: `payment.authorized.v1` — версия в типе.
Реестр схем (Avro/JSON Schema/Protobuf) с режимами совместимости (BACKWARD/FORWARD/FULL).
Major → dual-emit `v1` и `v2` на переходный период.


Модель версий и политика изменений

Semantic Versioning

MAJOR — ломающие изменения: удаление/переименование полей, смена ключей партиционирования, иной смысл статусов, ужесточение валидации.
MINOR — аддитивные: новые необязательные поля/эндпоинты/события, новые enum-значения при tolerant-reader.
PATCH — исправления без изменения контракта и семантики.

Deprecation & Sunset

Помечайте устаревшее (`Deprecated: true`, `@deprecated`), публикуйте sunset-дату, альтернативу и гайд миграции.
В HTTP — заголовки `Sunset`, `Deprecation`; в событиях — отдельное `.deprecation.notice`.
Ведите телеметрию usage для принятия решения о снятии.


Версионные стратегии по стилям

REST

Major-линии на /v1, /v2.
MINOR: расширение схем, `?fields=`, `?include=`; безопасные enum-расширения.
ETag/If-Match и идемпотентные POST для согласованности без ломок.
Ошибки — стабильный формат (`type`, `code`, `trace_id`).

gRPC

Вводите новые сервисы/методы для ломок: `PaymentsV2.Capture`.
Статусы ошибок и семантика deadline — часть контракта; изменение → новый метод/сервис.
Стриминг: договоритесь о порядке сообщений и не меняйте его в minor.

GraphQL

Добавляйте поля и типы свободно; удаления — через `@deprecated` + окно миграции; большой редизайн → новая схема (`/graphql-v2`).
Интроспекция и описания — must-have для миграций клиентов.

Events

Core vs enriched: ядро стабильно, обогащения живут рядом и версионируются отдельно.
Ключ партиционирования неизменен в пределах major-линии.
Major-миграции — `dual-emit` + миграция проекций/консьюмеров.


Negotiation и capability-флаги

Capabilities: клиент отправляет `X-Capabilities: risk_score,price_v2`; сервер отвечает расширенным представлением.
Prefer (HTTP) и «hints» для частичных ответов.
В сокетах/стримах — handshake-сообщение со списком поддерживаемых расширений.


Выпуск major-версий без боли

1. RFC/ADR: почему нужен major, что ломается, матрица рисков.
2. Dual-run: параллельный запуск `v1` и `v2` (двойная публикация событий, два gateway-роута, зеркалирование трафика).
3. Миграционные адаптеры: прокси/трансляторы `v1↔v2` для тяжелых клиентов.
4. Канарейка: по группам клиентов/топикам/тегам в gateway.
5. Sunset-план: даты, коммуникация, стенды, тестовые данные, мониторинг использования.


Роли платформы и инфраструктуры

API Gateway/Service Mesh: маршрутизация по версии, заголовкам, путям; rate-limit и auth per-version.
Schema Registry & Catalog: источник истины для спек/схем с историей диффов.
CI/CD: линтеры (Spectral, Buf), schema-diff (OpenAPI-diff, Buf breaking), CDC (Pact).
Observability: версия должна попадать в логи/трейсы/метрики.


Тестирование версий

Schema-diff в PR: блокировать breaking.
Consumer-Driven Contracts: провайдер проверяется против контрактов реальных потребителей.
Golden samples: эталонные ответы на версии.
E2E-канарейка: сравнение p95/p99, ошибок и таймаутов между версиями.
Replay для событий: проекции пересобираются на v2 без расхождений.


Миграция данных и баз

Для REST/gRPC: миграции БД координируются через expand-and-contract (добавь колонку → начни писать → переключи чтение → удали старое).
Для Events: dual-emit и миграция консьюмеров; иногда — репроигрывание лога на новые проекции.
Не делайте «больших взрывов» — дробите на шаги с откатами.


Взаимосвязь с безопасностью

Scopes per version: отдельные OIDC-scopes/роли для v1/v2.
Секреты/claim’ы токена — часть контракта; их смена = major.
PII/PCI — не расширяйте payload без надобности; новые поля — с минимумом привилегий.


Антипаттерны

Swagger-wash: спецификация обновлена, сервер — нет (или наоборот).
Переиспользование protobuf-тегов — тихая порча данных.
Смена enum-смыслов без major.
Глобальное `/v2` «ради косметики»: версия без факта ломки.
Забыли sunset/usage-метрики: невозможно снять старую версию безопасно.
Один общий топик для разных major: смешение порядков и ключей.


Чек-лист перед релизом

  • Изменения аддитивны или подготовлена отдельная major-линия.
  • Линтеры и schema-diff зеленые (breaking не пролез).
  • Обновлены SDK/примеров/документации, сноски про совместимость.
  • Включен tolerant reader в клиентах; enum-fallback протестирован.
  • Для major — план dual-run, адаптеры, канарейка, sunset-даты и рассылка.
  • Метрики/логи/трейсы содержат версию и сегментацию по ней.
  • Есть стенд и golden-наборы для сравнения v1↔v2.
  • Для событий — реестр схем в режиме BACKWARD/FULL, ключи партиционирования неизменны.

Примеры шаблонов

REST (URI + negotiation)

Маршрут: `/api/v2/orders/{id}`

Заголовок: `Prefer: include=items,customer`, `X-Capabilities: risk_score`

Deprecation: `Sunset: 2026-06-30`, `Link: ; rel="alternate"`

Protobuf/gRPC

proto package payments.v2;

service PaymentsV2 {
rpc Capture (CaptureRequestV2) returns (CaptureResponseV2);
}
💡 В v1 — пометка deprecated в описании и дата sunset в документации.

Events

`payment.captured.v2` (ядро) и `payment.enriched.v2` (детали).
На переходный период из продюсера идет `v1` и `v2`.


FAQ

Когда точно нужен `/v2`?
Когда меняются инварианты/семантика, удаляются поля/методы, меняется формат идентификаторов, ключ партиционирования, SLA/тайминги так, что ломаются клиенты.

Можно жить без явной версии в REST?
Только для мелких систем. Для внешних интеграций — лучше явные major-линии.

Какой срок держать устаревшую версию?
Зависит от экосистемы. Для внешних партнеров обычно 6–12 месяцев с ранним уведомлением и канарейкой.

Чем версионирование событий отличается от API?
События — append-only; новая семантика = новый тип `.v2` и dual-emit. Ключ партиционирования — часть контракта.


Итог

Стратегии версионирования — это процесс и инструменты: аддитивная эволюция по умолчанию, ясные major-линии, capability-negotiation, dual-run и sunset. Добавьте к этому автоматические проверки совместимости, телеметрию использования и дисциплину документации — и ваши API будут развиваться быстро, без «ночных миграций» и неожиданных падений у клиентов.

Contact

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

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

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

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

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

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