Єдиний API для провайдерів: дизайн, версія, сумісність
Повний текст статті
1) Навіщо «єдиний API» і що це таке
Єдиний API - це специфікація і набір ендпоінтів/подій, через які будь-який провайдер контенту (RGS, live-студія, джекпот, KYC/AML, афіліати) спілкується з платформою за одними правилами:- єдина ресурсна модель (players, sessions, bets, settlements, bonuses, jackpots, payments), загальні контракти подій та ідентифікатори, стандарти безпеки та зворотної сумісності, SDK/інструменти для прискорення інтеграцій.
Мета: скоротити time-to-integrate, знизити помилки на «грошових шляхах» і забезпечити передбачувані апгрейди.
2) Принципи дизайну
1. Domain-first. Спочатку словник та інваріанти (ставка, сеттлмент, ліміти RG), потім ендпоінти.
2. Compatibility by default. Будь-яка зміна - сумісне за замовчуванням; breaking-зміни строго по процесу.
3. Idempotency everywhere. Всі грошові команди повторювані без побічних ефектів.
4. Events are source of truth (в дистрибуції). Операції → події в шину; аналітика слухає шину, а не б'є OLTP.
5. Least privilege & zero-trust. Токени, підписи, сегментація по бренду/регіону.
6. Observability. Наскрізний'trace _ id', зрозуміла модель помилок, метрики p95/p99.
3) Ресурсна модель (спрощено)
Player: псевдо-ID гравця на стороні платформи, гео/валюта/статуси RG.
Session: канал між провайдером і платформою ('session _ id', TTL, гео/обмеження).
Bet: авторизація/дебет ставки.
Settlement: результат раунду і кредит виграшу.
Bonus / Wager: стан бонусу/залишку вейджера.
Jackpot: внески/тригери/виплати.
Event: незмінні доменні події (Kafka/аналоги).
Ідентифікатори: `tenant_id`, `brand_id`, `region`, `player_id`, `session_id`, `round_id`, `bet_id`, `settlement_id`. Всі - рядкові, глобально унікальні (UUID/KSUID/Snowflake), включаються в логи і події.
4) Контракти API: запити, відповіді, помилки
4. 1 Авторизація та безпека
OAuth2 Client Credentials або mTLS + підпис тіла запиту (HMAC/EdDSA).
Скоупи вигляду: `bets:write`, `settlements:write`, `sessions:read`, `events:publish`.
У кожному запиті обов'язкові заголовки:- `X-Trace-Id`, `X-Brand-Id`, `X-Region`, `X-Idempotency-Key`.
4. 2 Приклади ендпоінтів
Створення сесії
POST /v1/sessions
{
"player_id":"p_19f3",  "game_id":"studio:slot_forge_02",  "currency":"EUR",  "locale":"de-DE",  "constraints":{"max_bet":5,"rg_flags":["self_exclusion":false]}
}
→ 201
{
"session_id":"s_456",  "expires_at":"2025-10-23T19:10:00Z"
}Авторизація ставки (hold)
POST /v1/bets/authorize
Headers: X-Idempotency-Key: bet_r_8c12_1
{
"session_id":"s_456",  "bet_id":"b_001",  "round_id":"r_8c12",  "amount":{"amount":2. 00,"currency":"EUR"}
}
→ 200 { "status":"authorized","hold_id":"h_zz1" }Сетлмент
POST /v1/bets/settle
Headers: X-Idempotency-Key: settle_r_8c12_1
{
"bet_id":"b_001",  "round_id":"r_8c12",  "win":{"amount":14. 60,"currency":"EUR"},  "bonus_state":{"in_bonus":true,"freespins_left":7}
}
→ 200 { "status":"credited","settlement_id":"st_77" }4. 3 Помилки (єдина модель)
`code`: машинное имя (`RG_BLOCK`, `LIMIT_EXCEEDED`, `DUPLICATE`, `IDEMPOTENCY_MISMATCH`, `INVALID_STATE`, `AUTH_FAILED`).
`message`: коротко для людини.
`retryable`: `true/false`.
`trace_id`: для пошуку в логах.
Приклад:
409 CONFLICT
{
"code":"DUPLICATE",  "message":"Bet already authorized with a different amount",  "retryable":false,  "trace_id":"tr_a1b2c3"
}5) Подієва шина і схеми
5. 1 Базові топіки
5. 2 Схема події (Avro/JSON Schema)
json
{
"event_id":"uuid",  "event_type":"bet. settled",  "occurred_at":"2025-10-23T16:21:05Z",  "tenant_id":"brand-7",  "region":"EU",  "player_id":"p_19f3",  "trace_id":"tr_a1b2c3",  "payload":{
"round_id":"r_8c12",   "bet":{"amount":1. 00,"currency":"EUR"},   "win":{"amount":14. 60,"currency":"EUR"},   "in_bonus":true
},  "idempotency_key":"bet_r_8c12_1",  "schema_version":"1. 2. 0"
}Правила: backward-compatible еволюція схем, registry + контрактні тести.
6) Версія API: стратегії та правила
6. 1 Де зберігати версію
Path-версія: '/v1/...'( просто кешувати/маршрутизувати).
Header-версія: `Accept: application/vnd. platform. api+json; version=1. 2`.
Події: 'schema _ version'в полі події + registry.
Практика: path для HTTP, schema_version для подій, фічфлаги для точкових можливостей.
6. 2 SemVer і типи змін
PATCH (minor) - зворотносостикувальні: нові необов'язкові поля, нові ендпоінти, нові типи подій.
MAJOR — breaking: перейменування полів, зміна семантики, видалення. Дозволені тільки через новий '/vN/' і депрекацію старого.
6. 3 Стабільні контракти (що не можна ламати)
Імена і типи ключових полів ідентифікації ('_ id','idempotency _ key').
Грошову модель ('amount/currency', точність).
Семантику статусів ('authorized','credited','forfeited'і т. д.).
Ідемпотентність: поведінка при повторі строго визначена.
7) Сумісність та еволюція
7. 1 Додавання (safe)
Нові необов'язкові поля з дефолтами.
Нові події/ендпоінти без зміни існуючих.
Розширення enum з fallback в'unknown'.
7. 2 Зміни (risky)
Зміна типу поля (число → рядок).
Зміна обов'язковості (optional → required).
Розворот бізнес-логіки ('settle'раніше'authorize').
→ потрібна нова мажорна версія і міграційний гайд.
7. 3 Депрекація
Поле/ендпоінт позначається'deprecated _ since: 1. 7`, `removed_in: 2. 0`.
Комунікація: release notes, рассылка, deprecation-headers (`Sunset`, `Deprecation`).
Трасування використання «застарілих» шляхів для проактивних повідомлень партнерів.
8) Ідемпотентність та узгодженість
Заголовок'X-Idempotency-Key'обов'язковий для всіх записуючих операцій.
Семантика: повтор з тим же ключем → той же результат (200 з колишнім body).
Ключі прив'язані до композиції параметрів (наприклад,'bet _ id + amount').
Саги на довгих процесах: `authorize → commit/lock → settle → credit`; компенсації - подіями «rollback».
9) Пагінація, фільтри, сортування
Cursor-based пагінація (строго краще'page/limit'для великих потоків).
Уніфікація: `?cursor=...&limit=200&order=asc`.
У відповіді: `next_cursor`, `has_more`.
Фільтри: за часом ('occurred _ at _ from/to'),'tenant _ id','game _ id','status'.
10) Локалі, валюти, резидентність даних
Валюта в ISO-4217; точність зберігається в схемі ('scale'), розрахунки - в minor-units (cents).
Локалі - BCP 47 ('en-GB','pt-BR').
У кожному запиті - «region»; PII і грошові операції не перетинають регіони.
Маскування PII і RLS у вітринах BI.
11) Спостережуваність і ліміти
Обов'язкові заголовки: 'X-Trace-Id','X-Provider-Id', кореляція з подіями.
Метрики: p50/p95/p99 latency, error rate (за кодами), throughput, queue lag (для подій).
Rate limits: per provider / per brand; відповіді з'Retry-After'.
WORM-аудит критичних змін (ліміти, RTP-пули, формули джекпоту).
12) Тестування та якість контрактів
Контрактні тести (Pact/інші): провайдер ↔ платформа ↔ консьюмери подій.
Навантажувальні: «шторм» ставок/сеттлментів; цілі p95.
Хаос-кейси: дубль-доставки, out-of-order, затримки гаманця.
Пісочниця '/sandbox'з фіктивними грошима і тестовими'player _ id'.
13) SDK, генератори та документація
OpenAPI/AsyncAPI → генерація SDK (TypeScript/Java/Kotlin/Go/Rust).
Приклади коду для'authorize/settle/rollback', ретраїв і обробки помилок.
Live-док з прикладами запит/відповідь (curl + JSON), колекції Postman/Insomnia.
Changelog з типами змін і мітками сумісності.
14) Дорожня карта міграцій (приклад)
1. v1. 6 → v1. 7 (minor): додали поле'bonus _ state'в'settle'( optional).
2. v1. x EOL анонс: за 6 місяців - лист +'Deprecation'header + дашборд використання.
3. v2. 0 (major): окремий'wallet. commit'( раніше implicit), нове поле'settlement _ id'обов'язково.
4. Міграційний гайд: маппінг полів, timeline, фічфлаг «подвійного письма» (паралельна публікація'v1 '/' v2'подій).
5. Sunset v1: блокування нових інтеграцій, продовження тільки за SLA-винятками.
15) Чек-листи
Для архітекторів платформи
- Є єдиний словник доменних сутностей та інваріантів.
- OpenAPI/AsyncAPI + Schema Registry, semver, process депрекацій.
- Ідемпотентність на всіх write-операціях; ключі документовані.
- Єдина помилка-модель і коди.
- Саги і outbox/CDC на грошових шляхах.
- Rate-limits, observability, WORM-аудит.
- Пісочниця і контрактні тести доступні партнерам.
- Data residency і RLS/маскування.
Для провайдера
- Відправляю'X-Trace-Id'і'X-Idempotency-Key'завжди.
- Повтори запитів обробляю безпечно; дублі не створюю.
- Обробляю'Deprecation/Sunset'і читаю Changelog.
- Публікую/читаю події за схемами registry; зберігаю версію.
- Маю retry/backoff і дедуплікацію на своєму боці.
16) Анти-патерни (червоні прапори)
Ручні правки балансів/сеттлментів в БД.
Публікація подій «повз» outbox/CDC.
Відсутність idempotency → дублі виплат/дебетів.
Змішання PII/грошей різних регіонів без маркування'region'.
«Тихі» breaking-зміни без нової версії і депрекації.
Генерація SDK вручну (дрейф з реальної спеки).
Big-bang міграції без фічфлагів і подвійного листа подій.
Єдиний API - це не тільки «колекція ендпоінтів», а контракт екосистеми: узгоджений словник, стабільні грошові інваріанти, події з версіонуванням, зрозумілі правила сумісності та керовані депрекації. Спираючись на семантичну версіяцію, ідемпотентність, outbox/CDC, спостережуваність і сувору безпеку, платформа підключає провайдерів швидко і безболісно, а апгрейди перетворюються з ризику в рутину.
