GH GambleHub

Версионирование API и контрактная совместимость

TL;DR

Совместимость — это дисциплина, а не удача. Держите четкую политику версий (SemVer), математику изменений (что «ломает», что нет), контрактные тесты, регистры схем и Sunset-процедуры. Для денег и комплаенса — строгий REST/gRPC с vN, для UI-агрегаций — эволюционный GraphQL с `@deprecated`. Всегда: канареечный трафик, обратная совместимость ≥ один релизный цикл, миграционные гайды, телеметрия использования полей.

1) Базовые понятия и цели

Backwards-compatible (BC): новому серверу подходят старые клиенты.
Forwards-compatible (FC): старому серверу подходят новые клиенты (ограниченно).
Wire-совместимость: формат на «проволоке» не ломается (особенно важно для gRPC/Protobuf).
SemVer: `MAJOR.MINOR.PATCH` — ломаете контракт → повышаете MAJOR.

Цель: минимизировать ломающие изменения и обеспечивать предсказуемые окна миграции.

2) Матрица изменений: что можно, а что нельзя

Тип измененияRESTgRPC (Protobuf)GraphQL
Добавить поле (response)+ безопасно+ безопасно (новый field number)+ безопасно
Добавить опциональное поле (request)️ если сервер терпит отсутствие+ безопасно+ безопасно
Удалить поле- ломающее- если переиспользуете номер️ через `@deprecated` → удаление после окна
Переименовать поле- ломающее- (меняйте имя, номер сохраняйте)️ alias/два поля на время
Изменить тип/формат- ломающее- при смене wire-типа- если ломает схему
Менять семантику статусов/ошибок- ломающее- коды/детали — контракт- ломает клиентов
Менять порядок в Enum️ по значению безопасно️ если номера enum стабильны+ по имени безопасно
Новые endpoint/методы+ безопасно+ безопасно+ безопасно
Изменение пагинации/фильтров️ аккуратно, добавляйте опции+ через новые поля+ через новые аргументы

3) Политики для разных стилей API

3.1 REST

Версия в URI (`/v1/...`) или в домене (`api-v1.`). Заголовочная версия — только для внутренних случаев.
Добавляйте, не удаляйте: новые поля — ок, старые — помечайте как `deprecated` в схеме и оставляйте минимум на один цикл.
Статусы/ошибки: не меняйте коды и структуру `error.code/error.message/error.details`.
Идемпотентность неизменна: не превращайте безопасный `POST` с `Idempotency-Key` в «поведенчески другой» вызов.

3.2 gRPC / Protobuf

Номера полей — священные: не переиспользуйте удаленные номера, помечайте как `reserved`.
Только добавление новых optional/репит полей; «жесткие обязательные» — через валидацию, не `required`.
Версионные пакеты: `payments.v1`, `payments.v2`.
Совместимость сервисов: новые RPC → новый метод; поведение старых не меняем.

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

Эволюция без v2: добавляйте поля/типы; удаление — через `@deprecated(reason)` с анонсом окна.
Persisted Queries: для публичных клиентов используйте белый список запросов — легче контролировать совместимость.
Field-level authZ и телеметрия: знайте, какие поля реально используются, прежде чем удалять.

graphql type Payout {
id: ID!
amountMinor: Long!
currency: String!
comment: String @deprecated(reason: "Use note")
note: String
}

3.4 Вебхуки

Версия в пути (`/webhooks/v1/payments`) и фиксированный конверт события (`event_id`,`type`,`ts`,`data`).
Подписи/HMAC сохраните неизменными; новые алгоритмы — как опция с флагом.
Расширения — только через новые поля `data.` и `headers` — без удаления старых.

4) API Gateway и маршрутизация версий

Rules-based routing: по префиксу `/v1`, по заголовку `X-Api-Version`, по домену.
Shadow/Canary: отражайте часть продакшн-трафика на новую версию «в тень», сравнивайте ответы.
Rate/Quotas per-version: защищает старые клиенты во время миграции.

Sunset headers для REST:
  • `Sunset: ` — дата выключения версии
  • `Deprecation: true` — версия устаревает
  • `Link: ; rel="deprecation"` — на changelog/гайд миграции
Пример (Nginx-style, упрощенно):
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) Регистры схем и контракты

OpenAPI / JSON Schema для REST; Protobuf descriptors для gRPC; SDL registry для GraphQL.
CI-проверки: linters + «breaking-changes check» при PR.
Consumer-Driven Contracts (CDC): тесты потребителей (Pact/аналог) — защита от незаметных ломаний.
Changelog: machine-readable (например, `CHANGELOG.md` + релиз-ноты в реестре).

6) Эволюция полей: практические правила

ID/ключи: не меняйте формат (UUID↔int) без нового поля `_v2` и переходного периода.
Время/валюта: держите UTC ISO-8601/epoch и amount_minor + currency; не меняйте масштаб (копейки/центы).
Enum: добавляйте значения — ок; не меняйте смысл старых. Для REST — отдавайте string-значения, а не ints.
Пагинация: cursor-based стабильнее; не меняйте семантику курсора.

7) Деприкация и «Sunset»-процедура

1. Анонс (T-90/60): changelog, рассылка партнерам, заголовки `Deprecation/Sunset`.
2. Дублирующий период: V1 и V2 работают параллельно; V1 снабжен предупреждениями в ответах/логах.
3. Телеметрия использования: кто еще зовет V1? точечные контакты.
4. Заморозка V1: только багфиксы/без фич.
5. Выключение (Sunset): 410 Gone или блок-страница с инструкцией миграции.

8) Релизы без боли: стратегии выкладки

Blue/Green или Weighted routing: 1–5–25–50–100% трафика.
Compatibility window: минимум 1–2 минорных релиза, чаще 6–12 месяцев для внешних API.
Feature Flags: чтобы включать новые поля/ветки логики без смены версии.
Read/Write-расщепление: сначала добавьте поддержку чтения нового поля, затем начните писать его.

9) Тестирование совместимости (пакет практик)

Golden-тесты на ответы старых версий.
Diff-тесты схем: запрет breaking в CI.
Replay продакшн-трасс на staging для V2 (shadow).
Back/Forward сценарии: новый клиент на старом сервере и наоборот (там, где FC допустим).
Контрактные тесты вебхуков: проверка подписи, формата, времени.

10) Метрики и SLO процесса версионирования

% клиентов на последней MINOR (цель ≥ 80% перед Sunset).
Ошибки совместимости/недоступности на выпуск (цель — 0).
Доля вызовов устаревшей версии (убывающая к Sunset).
Время миграции клиента (медиана/п95).
Latency/regression delta между версиями (не хуже базовой).

11) Примеры артефактов

OpenAPI (фрагмент, деприкация поля):
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 (reserved и v2 пакет):
proto syntax = "proto3";
package payouts. v1;
message Payout { reserved 5; string id=1; int64 amount_minor=2; string currency=3; }
GraphQL (деприкация):
graphql type Query { payout(id: ID!): Payout }

12) Версионирование смежных каналов

SDK/CLI: SemVer + зависимость от API-версии, совместимость оговорена в README.
События/стримы (WS/Kafka): версия в `envelope.version`; новые атрибуты — опциональны; дедуп и резюм работают одинаково между версиями.
Отчетность/CSV: версия в имени файла/шапке; добавляйте столбцы справа; не меняйте порядок/типы.

13) Governance и роли

Владелец контракта (domain owner), API Steward (правила и линтеры), Release Manager (Sunset/коммуникации).
RFC-процесс для breaking-изменений: бизнес-обоснование, план миграции, артефакты, даты.
Единый каталог API: где видны схемы, версии, Sunset-календарь, контакт.

14) Анти-паттерны

«Тихие» ломания: меняем статус/ошибку/тип поля без версии.
Переиспользование protobuf-номеров — разрушает реплей и старые клиенты.
GraphQL без телеметрии использования полей — удаление «наощупь».
Глобальная v2 всего — мегамиграция вместо точечной эволюции.
Версия в query-параметре для публичного API — неочевидная и уязвимая схема.
Нет миграционных гайдов и примеров — партнеры буксуют, сроки срываются.

15) Check-list релиза новой версии

  • Обновлена схема (OpenAPI/Protobuf/SDL), пройдены линтеры и breaking-checks.
  • Добавлены интеграционные и контрактные тесты (CDC).
  • Готовы SDK/пример кода/миграционный гайд и Changelog.
  • Включены `Deprecation/Sunset` (для старой версии) + страница «How to migrate».
  • Canary/Shadow план, алерты и дашборды сравнения метрик.
  • Обратная совместимость сохранена на согласованный срок.
  • План отката (rollback) и матрица рисков согласованы.

Резюме

Стабильное API — это процесс, а не «раз и навсегда». Живите по правилам: SemVer + add-only эволюция + регистр схем + контрактные тесты + Sunset-процедуры. Разделяйте стили (REST/gRPC/GraphQL) и их политики, маршрутизируйте версии на API Gateway, выкатывайте канарейками, измеряйте эффект. Так вы избежите «ломающих сюрпризов», ускорите интеграции партнеров и сохраните предсказуемость для денежных и комплаенс-критичных доменов.

Contact

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

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

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

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

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

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