REST, gRPC и вебхуки в iGaming: паттерны и анти-паттерны
Полный текст статьи
1) Карта протоколов: кто за что отвечает
REST — универсальные синхронные запросы по HTTP/JSON. Прозрачный кеш, простая отладка, удобен для B2B интеграций и админ-API.
gRPC — высокопроизводительный двоичный RPC поверх HTTP/2: низкая латентность, стримы, жёсткие схемы. Хорош для горячих денежных путей (wallet/settle), внутренних сервисов и долгоживущих стримов (live).
Вебхуки — обратные вызовы (callback) от получателя к отправителю. Используются для событий («денежка упала», «лимит сработал»), где инициатор — не всегда тот, кто ждёт результат.
Золотое правило:- Деньги идут по синхронному RPC (REST/gRPC) с жёсткими инвариантами и идемпотентностью. Телеметрия и бизнес-события — асинхронно (вебхуки + шина событий).
2) Типовые пути и рекомендованные каналы
3) Контракт-ориентированный дизайн
3.1 REST (фрагменты)
POST /v1/bets/authorize
Headers: X-Idempotency-Key: bet_r_8c12_1, X-Trace-Id: tr_a1b2
{
"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"}
409
{"code":"DUPLICATE","message":"Bet already authorized","retryable":false,"trace_id":"tr_a1b2"}3.2 gRPC (protobuf, упрощённо)
proto syntax = "proto3";
package wallet.v1;
message Money { int64 minor_units = 1; string currency = 2; } // cents message AuthorizeBetReq { string session_id=1; string bet_id=2; string round_id=3; Money amount=4; string idempotency_key=5; }
message AuthorizeBetRes { string status=1; string hold_id=2; }
service Wallet {
rpc AuthorizeBet(AuthorizeBetReq) returns (AuthorizeBetRes);
rpc SettleBet(SettleReq) returns (SettleRes);
}3.3 Вебхуки (пример подписки)
POST https://provider.example/webhooks
{
"topic":"wallet.credit.ok",  "callback_url":"https://rgs.example/journal",  "secret":"", "version":"1.2"
}
POST https://rgs.example/journal
Headers: X-Signature: sha256=..., X-Trace-Id: tr_a1b2
{
"event_type":"wallet.credit.ok",  "schema_version":"1.2.0",  "event_id":"uuid",  "payload":{"player_id":"p_19f3","amount":{"minor_units":1460,"currency":"EUR"}}
}4) Идемпотентность и согласованность
Всегда требуйте `X-Idempotency-Key` на write-операциях (REST/gRPC metadata). Повтор → тот же ответ.
Композиция ключа привязана к бизнес-параметрам (например, `bet_id + amount`).
Саги для длинных процессов (authorize → commit/lock → settle → credit).
Outbox/CDC: события фиксируются атомарно рядом с транзакцией и публикуются извне.
5) Версионирование и совместимость
REST — `/v1/...` + `Deprecation/Sunset`-заголовки; gRPC — `package wallet.v1`; события — `schema_version` в телах + реестр схем.
SemVer: minor — поля optional/новые endpoints; major — новый путь/пакет, «двойное письмо» событий на миграции.
Никогда не меняйте семантику денежных статусов без major-версии.
6) Безопасность транспортов
mTLS на всех S2S; для вебхуков — подпись тела (HMAC/EdDSA) + timestamp и окна валидности.
Ограничение скоупов (OAuth2 CC) и сегментация ключей per brand/region.
Zero-trust: сетевые политики, короткоживущие токены, Vault/HSM, WORM-аудит критичных действий.
7) Наблюдаемость и SLO
Сквозной `trace_id` в REST, gRPC metadata и вебхуках.
Метрики: p50/p95/p99 latency, error rate по кодам, throughput, lag очередей.
SLO-минимум (ориентиры):- Wallet p95 `< 150 мс` (Authorize/Settle), REST публичных B2B p95 `< 300 мс`, Вебхуки доставлены `< 5 мин` 99-й перцентиль, «Потерянных/дублированных сеттлментов» = 0.
8) Ретраи, backoff и порядок доставки
REST/gRPC: экспоненциальный backoff, джиттер, ограничение длительности (deadline/timeout).
Вебхуки: повторяемая доставка до `2xx`; сохранение порядка по ключу (`player_id/round_id`) или дедупликация на приёмнике.
Анти-штормы: лимит параллельных ретраев, circuit breaker, rate limit.
9) Паттерны интеграции
Паттерн A: «Деньги синхронно, события асинхронно»
1. RGS → Wallet (gRPC/REST) `authorize` → `settle/credit`.
2. Параллельно публикуется `bet.settled` в шину, а провайдер получает вебхук-квитанцию.
Плюс: быстрые деньги, наблюдаемость. Минус: нужно два контура.
Паттерн B: «Streaming live»
Live-ядро ↔ Bridge через gRPC streaming (статусы стола, окно ставок).
Денежные операции — отдельные unary RPC; события — в шину/вебхуки.
Плюс: минимальная задержка живых статусов.
Паттерн C: «B2B публичный REST»
Каталоги/бонусы/аффилиаты/отчёты — REST с cursor-пагинацией, фильтрами, ETag.
Плюс: простая интеграция партнёров.
10) Анти-паттерны (красные флаги)
Денежные операции только через вебхуки (без синхронного подтверждения).
Отсутствие `Idempotency-Key` → дубли дебетов/кредитов.
Публикация событий в обход outbox/CDC (теряются события).
Вебхуки без подписи/временной метки → подмена.
Смешение PII/денег разных регионов в одном канале без тегов `region/tenant`.
Большие binary payload в вебхуках (ломают ретраи и лимиты).
Нулевые деградации: падение вебхуков блокирует расчёт денег.
gRPC без deadline и без backoff — зависшие соединения, исчерпание ресурсов.
11) Чек-листы
Архитектор/платформа
- Деньги по gRPC/REST c идемпотентностью, события — вебхуки/шина.
- Outbox/CDC на всех денежных путях.
- `/vN` и schema registry; Deprecation/Sunset процесс.
- mTLS + подписи вебхуков; секректы per brand/region.
- SLO-дашборды p95/p99, error rate, webhook-lag.
- DR/хаос-учения: дубль-доставки, out-of-order, отвал региона.
Провайдер/RGS
- Отправляю `X-Trace-Id` и `X-Idempotency-Key`.
- Ретраи с backoff и дедупликацией; готов к повторной доставке вебхуков.
- Обновляю версии контрактов; реагирую на `Deprecation/Sunset`.
- Логи/метрики по кодам ошибок и времени.
12) Мини-решения для острых кейсов
Safari/ITP и third-party ограничения: деньги — в хосте (REST/gRPC), iFrame-контент общается через `postMessage`; вебхуки от хоста, не от iFrame.
Мультибренд: теги `tenant_id/brand_id/license` в заголовках и событиях; ключи/сертификаты раздельные.
Большие всплески (турниры): перед вебхуками — буфер/очередь с DLQ; при перегрузе — «no new sessions»/«pause non-core hooks».
13) Примеры SLO-ориентированных алертов
Wallet.Authorize p95 > 150 мс 5 мин подряд.
Ошибки `DUPLICATE/IDEMPOTENCY_MISMATCH` > 0.5% за 10 мин.
Webhook lag p99 > 180 c по теме `bet.settled`.
Consumer lag в Kafka > 30 с для `wallet.credit.`.
14) Вывод
REST, gRPC и вебхуки в iGaming — это не взаимозаменяемые технологии, а части одной операционной модели.
REST/gRPC держат денежные инварианты: низкая латентность, идемпотентность, строгие SLA.
Вебхуки/шина обеспечивают прозрачность и масштаб: события, телеметрия, интеграции.
Добавьте outbox/CDC, версионирование, подписи и наблюдаемость — и получите архитектуру, где деньги двигаются быстро и безопасно, события не теряются, а апгрейды проходят безболезненно.
