GH GambleHub

Реестр схем и эволюция данных

Зачем нужен реестр схем

Реестр схем — это централизованный источник истины для контрактов данных (API, события, потоки, сообщения, хранилища), который обеспечивает:
  • Предсказуемую эволюцию: правила совместимости и автоматическая проверка «ломок».
  • Повторяемость и прозрачность: история версий, кто/когда/зачем менял.
  • Стандартизацию: единые названия, форматы ошибок, поля трассировки, PII-метки.
  • Интеграцию с CI/CD: блокировка breaking-изменений до продакшена.

Реестр связывает Protocol-first и контрактную совместимость, делая изменения быстрыми и безопасными.


Форматы и области применения

JSON Schema: REST/HTTP полезные нагрузки, документы, конфигурации.
Avro: событийные шины (Kafka/Pulsar), compact/эволюция через ID полей.
Protobuf: gRPC/RPC, бинарно-эффективен, строгие теги.
GraphQL SDL: схема типов и директив, эволюция через `@deprecated`.
SQL DDL как артефакт: фиксируем договоренные представления (например, внешние витрины) — с осторожностью.

💡 Один реестр может хранить сразу несколько типов артефактов, но с раздельными политиками совместимости.

Режимы совместимости

BACKWARD: новые схемы читают старые данные/сообщения. Подходит для продюсера, который расширяет payload аддитивно.
FORWARD: старые потребители корректно читают новые данные (требует tolerant reader).
FULL: совмещает оба (строже, удобнее для публичных контрактов).
NONE: без проверок — только для песочниц.

Рекомендации:
  • Events: чаще BACKWARD (продюсер расширяет payload опционально).
  • Публичные API: FULL или BACKWARD + строгий tolerant reader на клиентах.
  • Внутренние прототипы: временно NONE, но не на trunk.

Безопасные (аддитивные) vs. опасные изменения

Аддитивные (ОК):
  • Добавление необязательного поля/типа.
  • Расширение enum новыми значениями (при tolerant reader).
  • Добавление альтернативной проекции/события (`.enriched`).
  • Ослабление ограничений (`minLength`, `maximum` ↑, но не ↓).
Опасные (ломают):
  • Удаление/переименование полей или изменение их типа/обязательности.
  • Изменение семантики статусов/кодеков/порядка в потоках.
  • Переиспользование protobuf-тегов.
  • Смена ключа партиционирования в событиях.

Организация реестра

Нейминг и адресация

Группы/пространства: `payments`, `kyc`, `audit`.
Имена: `payment.authorized.v1` (events), `payments.v1.CaptureRequest` (gRPC), `orders.v1.Order` (JSON Schema).
Мажор в имени, миноры — в метаданных/версии схемы.

Метаданные

`owner` (команда), `domain`, `slas` (SLO/SLA), `security.tier` (PII/PCI), `retention`, `compatibility_mode`, `sunset`, `changelog`.

Управление жизненным циклом

Draft → Review → Approved → Released → Deprecated → Sunset.
Автоматические валидаторы/линтеры, ручной design-review (API Guild), release notes.


Интеграция в CI/CD

1. Pre-commit: локальные линтеры (Spectral/Buf/Avro tools).
2. PR-пайплайн: schema-diff → проверка compatibility mode; блокируем breaking.
3. Artifact publish: пуш согласованной схемы в реестр + генерация SDK/моделей.
4. Runtime-guard (опционально): шлюз/продюсер валидирует payload против актуальной схемы.

Пример шагов в PR:
  • `openapi-diff --fail-on-breaking`
  • `buf breaking --against
    `
  • `avro-compat --mode BACKWARD`
  • генерация golden samples и прогон CDC-тестов.

Эволюция схем: практики

Additive-first: новые поля — `optional/nullable` (JSON), `optional` (proto3), default в Avro.
Модель обратной пирамиды: ядро стабильно, обогащения — рядом и опциональны.
Dual-emit/dual-write для major: параллельно публикуем `v1` и `v2`.
Sunset-план: даты, использование, предупреждения, адаптеры.
Tolerant reader: клиенты игнорируют неизвестные поля и корректно обрабатывают новые enum.


Примеры схем и проверок

JSON Schema (фрагмент, аддитивное поле)

json
{
"$id": "orders.v1.Order",
"type": "object",
"required": ["id", "status"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"status": { "type": "string", "enum": ["created", "paid", "shipped"] },
"risk_score": { "type": "number", "minimum": 0, "maximum": 1 }
},
"additionalProperties": true
}
💡 Добавлен `risk_score` как необязательный → BACKWARD совместимо.

Avro (default для совместимости)

json
{
"type": "record",
"name": "PaymentAuthorized",
"namespace": "payment.v1",
"fields": [
{ "name": "payment_id", "type": "string" },
{ "name": "amount", "type": "long" },
{ "name": "currency", "type": "string" },
{ "name": "risk_score", "type": ["null", "double"], "default": null }
]
}

Protobuf (не переиспользуйте теги)

proto syntax = "proto3";
package payments.v1;

message CaptureRequest {
string payment_id = 1;
int64 amount = 2;
string currency = 3;
optional double risk_score = 4; // additive
}
// tag=4 зарезервирован под risk_score, его нельзя менять/удалять без v2

Регистр событий и партиционирование

Именование событий: `domain.action.v{major}` (`payment.captured.v1`).
Ключ партиционирования — часть контракта (`payment_id`, `user_id`).
Core vs Enriched: `.v1` (ядро) и `.enriched.v1` (детали).
Совместимость в реестре: режимы на уровне темы/типа; CI отказывает несовместимым изменениям.


Управление миграциями

Expand → Migrate → Contract (REST/gRPC):

1. добавить поля/таблицы; 2) начать писать/читать новые поля; 3) удалить старое после sunset.

  • Dual-emit (Events): параллельно `v1`/`v2`, миграция консьюмеров/проекций, затем снятие `v1`.
  • Replay: пересборка проекций из лога на новую схему (только при совместимости и миграторах).
  • Адаптеры: гейтвей/прокси, переводящие `v1↔v2` для сложных клиентов.

Безопасность и комплаенс

PII/PCI метки в схеме: `x-pii: true`, `x-sensitivity: high`.
Политики доступа: кто может публиковать/изменять схемы (RBAC), подписывать релизы.
Криптография: подпись версий схем, неизменяемые журналы аудита (WORM).
Право на забвение: указывайте поля, требующие шифрования/крипто-стирания; guidance в реестре.


Наблюдаемость и аудит

Дашборды: количество изменений, типы (minor/major), доля отклоненных PR, использование версий.
Аудит-трейл: кто изменил схему, ссылки на PR/ADR, связанный релиз.
Runtime-метрики: процент сообщений, не прошедших валидацию; инциденты совместимости.


Инструменты (примерный стек)

OpenAPI/JSON Schema: Spectral, OpenAPI Diff, Schemathesis.
Protobuf/gRPC: Buf, buf-breaking, protoc linters.
Avro/Events: Confluent/Redpanda Schema Registry, Avro-tools, Karapace.
GraphQL: GraphQL Inspector, GraphQL Codegen.
Реестры/каталоги: Artifact Registry, Git-based registry, Backstage Catalog, custom UI.
Документация: Redocly/Stoplight, Swagger-UI, GraphiQL.


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

Swagger-wash: схема не отражает реальность сервиса (или наоборот).
Отключенная проверка совместимости: «надо срочно» → прод ломается.
Переиспользование protobuf-тегов: тихая порча данных.
Единый режим совместимости «для всего»: разные домены требуют разных режимов.
Сырые CDC как публичные схемы: утечка БД-модели наружу, невозможность эволюции.


Чек-лист внедрения

  • Определен формат артефактов и compatibility mode по доменам.
  • Настроены линтеры и schema-diff в CI, PR блокируется при breaking.
  • Включен tolerant reader у клиентов; `additionalProperties=true` (где уместно).
  • Мажорные изменения проходят через RFC/ADR, есть sunset-план и dual-emit/dual-write.
  • Схемы помечены PII/PCI и уровнями доступа; включен аудит.
  • Дашборды по использованию версий и отказам совместимости.
  • Генерация SDK/моделей из реестра — часть пайплайна.
  • Документация и golden samples обновлены автоматически.

FAQ

Можно ли без реестра — хранить схемы в Git?
Да, но реестр добавляет API совместимости, поиск, метаданные, централизованную политику и «on-the-fly» валидацию. Лучший вариант — Git как storage + UI/политики поверх.

Как выбирать режим совместимости?
Смотрите на направление изменений: если продюсер расширяет payload — BACKWARD. Для публичного API/SDK — FULL. Для быстрых прототипов — временно NONE (не на trunk).

Что делать при необходимости ломки?
Готовим v2: dual-emit/dual-run, sunset-даты, адаптеры, телеметрию использования, миграционные гайды.

Нужно ли валидировать payload в рантайме?
Для критичных доменов — да: это предотвращает «мусорные» сообщения и ускоряет диагностику.


Итог

Реестр схем превращает эволюцию данных из рискованной импровизации в управляемый процесс: единые правила совместимости, автоматические проверки, понятные версии и прозрачная история. Добавьте к нему дисциплину additive-first, tolerant reader, dual-emit и sunset — и ваши контракты будут развиваться быстро, без ломок и ночных инцидентов.

Contact

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

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

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

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

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

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