Protocol-first дизайн
Что такое Protocol-first
Protocol-first — это подход, в котором контракт взаимодействия между компонентами (сервисами, клиентами, внешними партнерами) проектируется и фиксируется раньше реализации. Код, хранилища, инфраструктура и документация подчиняются контракту и автоматически из него генерируются, а не наоборот.
В отличие от «code-first», где API — лишь побочный продукт кода, Protocol-first делает протокол первичным артефактом: ему принадлежат понятия домена, модели данных, статусы, ошибки, семантика идемпотентности, SLO/SLI и даже политика версий.
Зачем это нужно
Согласованность и предсказуемость интерфейсов в масштабах организации.
Быстрый онбординг (автогенерация SDK/стабов/клиентов, единые ошибки и коды).
Надежная эволюция (совместимость схем, контракты-тесты, четкая политика версий).
Продуктовый фокус: обсуждаем поведение, SLA и UX интеграции до написания кода.
Автоматизация: CI/CD собирает артефакты (клиенты, серверные заглушки, валидаторы) из одного источника истины.
Безопасность и комплаенс: права, маскирование PII, политики ретенции закреплены в контракте.
Ядро подхода
1. Единый источник истины (SSOT) — машинно-читаемые спецификации:
REST: OpenAPI/JSON Schema.
События и стриминг: AsyncAPI, Avro/JSON Schema.
RPC: Protobuf (gRPC), Thrift, Smithy.
GraphQL: SDL + директивы/политики.
2. Договоренности до реализации: глоссарий домена, коды ошибок, семантика идемпотентности, дедлайны, ретраи, дедупликация.
3. Автогенерация: клиенты/серверные стабы, типы, SDK, контракты-тесты, моки, Postman-коллекции, Terraform/OpenAPI Gateway-конфиг.
4. Governance: линтеры/политики (naming, пагинация, фильтры, ошибки), review через API-гильдию, change-advisory для мажорных версий.
5. Совместимость: строгая проверка «additive-only» диффов, семантическое версионирование, canary/consumer-driven тесты.
6. Наблюдаемость на уровне контракта: корреляционные ID, модели ошибок, бюджеты задержек прописаны в протоколе.
Как выглядит процесс (скелет)
1. Инициация: продуктовый бриф → user journeys → API/Protocol PRD (ресурсы/методы/события, SLA/SLO, ошибки, лимиты).
2. Моделирование: черновик спецификации (OpenAPI/AsyncAPI/Proto) + схемы данных, словарь терминов.
3. Договора и UX интеграции: примеры полезной нагрузки, контракты ошибок, карты статусов, правила версионирования.
4. Ревью и governance: линтеры/стандарты, обсуждение доменных инвариантов, lock-in MGC (минимальный гарантийный контракт).
5. Автогенерация артефактов: SDK, стабы, тестовые фикстуры, заглушки инфраструктуры (Gateways, IAM scopes).
6. Реализация и контракт-тесты: поставщик и потребители проходят проверку совместимости в CI.
7. Наблюдаемость и SLO: трассировка по correlation-id, error catalog, бюджеты ретраев/таймаутов.
8. Релизы и эволюция: additive-first, deprecation policy, canary, A/B capability flags.
Протоколы и стили взаимодействия
REST/HTTP
Стандарты: ресурсная модель, `GET/POST/PATCH/DELETE`, пагинация (cursor), фильтры, сортировка.
Поля и схемы: JSON Schema, форматы (`date-time`, `uuid`), инварианты (regex/enum/min-max).
Ошибки: единый формат (`type`, `code`, `title`, `detail`, `trace_id`), маппинг на HTTP стеки.
Контроль изменений: ETag/If-Match, идемпотентные ключи для POST, эксплицитные семантики 409/422.
gRPC/RPC
Protobuf: стабильная нумерация тегов, `optional`, запрет переиспользования удаленных полей.
Deadlines и приоритеты в контракте; стабильные статусы (OK, INVALID_ARGUMENT, FAILED_PRECONDITION, etc.).
Streaming: спецификация порядка сообщений, backpressure, финальные трейлеры.
Event-driven (Kafka/NATS/SNS/SQS)
AsyncAPI: темы/каналы, ключи партиционирования, соглашения о ключах дедупликации, ретенции, семантика «ровно-один раз» vs «по крайней мере один раз».
Событие-ядро и обогащения: разделяйте минимальный payload и расширения; версионируйте `event_type`/`schema_version`.
Идемпотентность: `event_id`, `producer_id`, policy по ретраям и дедупликации.
GraphQL
SDL как контракт, директивы для депрекейта, лимиты глубины и сложностей, контракт ошибок (error codes/extensions).
Интеграция с архитектурными принципами
Inverse Pyramid / Critical Path First: в спецификации выделять MGC (обязательный минимум), расширения — через `?include=`/capabilities.
Paved Roads: набор готовых шаблонов спецификаций (payment, KYC, audit, search, files) + линтеры.
API Gateways & Service Mesh: политики на основе контракта (rate-limits, auth scopes, retries, circuit-breakers).
Версионирование и эволюция
Semantic Versioning:- Minor = только аддитивные поля/каналы.
- Major = ломающие изменения (удаления, переименование, изменение семантики).
- Deprecation Policy: окна поддержки, заголовки `Sunset`, события-уведомления.
- Consumer-Driven Contracts (CDC): проверяем, что текущее API удовлетворяет конкретным потребителям.
- Каталог схем: реестр (Schema Registry/Artifact Registry) с историей и правилами совместимости (BACKWARD/FORWARD/FULL).
Безопасность и комплаенс
Аутентификация/авторизация как часть контракта (OAuth2/OIDC scopes, mTLS, JWT claims).
PII/PCI: маскирование, форматы токенизации, поля с особыми режимами хранения/TTL.
Политики аудита: обязательные атрибуты (`actor`, `subject`, `action`, `occurred_at`, `trace_id`).
Лимиты: rate limit headers, квоты, размеры сообщений, дедлайны.
Наблюдаемость по контракту
Correlation/Request-ID: обязательно в спецификации.
Error Catalog: фиксированный список кодов и SLA по устранению.
SLI/SLO: p50/p95 latency, доля успешных ответов, доля совместимых событий, доля идемпотентных повторов.
Тестирование и качество
Contract tests (поставщик ↔ потребитель), schema diff в CI, генерация мок-серверов.
Golden samples: эталонные примеры запросов/ответов, фикстуры для e2e.
Chaos/latency injection: проверка таймаутов/ретраев, деградация расширений при сохранении MGC.
Примерные доменные шаблоны
Платеж (REST + события)
`POST /payments` (идемпотентный ключ) → `201 Created` с `payment_id`, `status=authorized`.
Событие `payment.authorized.v1` (ядро): `{ payment_id, amount, currency, method, occurred_at }`.
Расширение `payment.enriched.v1`: риск-скор, гео, device-fingerprint.
Ошибки: `422` (валидация), `402` (payment required), `409` (duplicate).
SLA: авторизация ≤ 800мс p95; событие ядра ≤ 2с lag p95.
KYC (gRPC + очереди)
RPC `StartVerification(user_id)` → `operation_id`.
События прогресса в топике `kyc.status.v1` (`PENDING` → `APPROVED/REJECTED`).
Контракт оговаривает PII-поля, срок хранения, маскирование, причинные коды отказа.
Аудит (Event-only)
`audit.recorded.v1` (ядро): `actor`, `subject`, `action`, `occurred_at`, `trace_id`.
Обогащение: IP, device, geo — отдельным событием/потоком, не блокирует ядро.
Инструменты и автоматика (примерный стек)
Спеки: OpenAPI/AsyncAPI/Protobuf/Avro/GraphQL SDL.
Линтеры: Spectral, OpenAPI Diff, Buf (protobuf), Confluent SR compatibility checks.
Генерация: OpenAPI Generator, Buf/Protoc, GraphQL Codegen, AsyncAPI Generator.
Гейтвей: Kong/Apigee/Azure/GCP GW, Envoy.
Тесты: Pact/CDC, Dredd, Schemathesis, Hoverfly, MockServer.
Реестр: Git-каталог схем + Schema Registry/Artifact Registry.
Документация: Redocly/Stoplight/Swagger-UI/GraphiQL/Explorer.
Анти-паттерны
Code-first by accident: «сначала MVP на контроллерах», спецификация пост-фактум, расхождение документации и поведения.
Swagger-wash: формальная OpenAPI без реальных правил (ошибки, лимиты, SLA, версии).
Слом совместимости: удалили поле/изменили тип без major-версии; переиспользование protobuf-тегов.
«Толстый» ответ без пагинации/фильтров; отсутствие идемпотентности.
Секьюрити вне контракта: auth/Scopes описаны в вики, но не в спецификации.
Взаимосвязь с организацией процесса
API Guild: попечители стандартов, ревью изменений, обучение.
Design Docs: на каждое API — PRD, ADR (решения), SLA, матрица рисков.
Change Management: RFC-процесс, release notes, миграционные гайды, deprecation-таймлайн.
Paved Road & Templates: генераторы каркасов сервиса из спецификации (скелет хэндлеров, валидация, логирование).
Чек-листы
Перед стартом
- Есть PRD и глоссарий домена.
- Выбран стиль (REST/gRPC/Event/GraphQL) и формат схем.
- Определены MGC, ошибки, SLA/SLO, правила идемпотентности.
В разработке
- Спецификация проходит линтеры и review.
- Автогенерация SDK/стабов/фикстур настроена.
- Контракт-тесты (CDC) включены в CI; schema-diff блокирует несовместимые изменения.
Перед релизом
- Документация для интеграторов с примерами и кодами ошибок.
- Наблюдаемость по контракту: correlation-id, error catalog, дашборды SLI.
- Политика версионности и deprecation объявлены.
FAQ
Чем Protocol-first отличается от API-first?
Часто термины используют как синонимы. В этой статье под Protocol-first мы подчеркиваем строгость контракта и охват всех стилей (REST/RPC/Events/GraphQL), включая SLA, безопасность и наблюдаемость.
Не замедлит ли это разработку?
Старт может быть чуть дольше, но затем выигрываем на интеграциях, стабильности и скоростях параллельной разработки (автогенерация, стабильные SDK).
Что делать с быстрыми экспериментами?
Используйте «черновые» версии схем (draft), feature flags и песочницы, но не пропускайте линтеры и базовые правила совместимости.
Итог
Protocol-first дизайн делает контракт центром архитектуры: согласовываем поведение, фиксируем схемы, автоматизируем генерацию и тесты, эволюционируем аддитивно. В результате получаем предсказуемые интеграции, высокую скорость развития и устойчивость систем к изменениям масштаба и команды.