При проектировании интеграций вы выбираете не только «какие системы связать», но и как клиент будет ждать ответ. REST, gRPC и GraphQL — три распространённых способа построить синхронный request–response; в заголовке они названы «протоколами» для краткости, хотя REST — архитектурный стиль, gRPC — RPC-фреймворк, GraphQL — язык запросов и runtime. Фокус статьи — unary-вызов (один запрос → один ответ); streaming и subscriptions затронуты с оговорками. Статья помогает зафиксировать различия в спецификации, выбрать подход по контексту и не смешивать синхронный вызов с длинными бизнес-процессами.

1. Суть темы

Синхронное взаимодействие в интеграции — паттерн, при котором вызывающая сторона отправляет запрос и ожидает ответ в рамках одного логического вызова (request–response). Клиент блокируется или логически «висит» до получения результата, ошибки или таймаута. Это контрастирует с асинхронной доставкой через очереди и события, где ответ приходит позже и по другому каналу.

REST, gRPC и GraphQL — основные современные способы построить синхронный API:

ПодходСуть для аналитикаТранспорт и формат
RESTАрхитектурный стиль поверх HTTP: ресурсы, URI, методы, представленияHTTP/1.1–2, чаще JSON
gRPCRPC-фреймворк со строгим контрактом в Protocol BuffersHTTP/2, бинарная сериализация
GraphQLЯзык запросов и runtime: одна схема, клиент выбирает поляHTTP (обычно POST), JSON

В корпоративных ландшафтах (банки, гос, ERP) по-прежнему встречается SOAP и XML-RPC как синхронный legacy — см. 07.02 Принципы работы HTTP, REST, SOAP и 10.01.05 Шаблон спецификации SOAP API; в этой статье они не сравниваются детально, но учитывайте их при инвентаризации интеграций.

Scope статьи: unary REST/gRPC и query/mutation GraphQL. Server/client/bidirectional streaming gRPC и GraphQL subscriptions — полусинхронные или длинные сессии; на sequence diagram помечайте их отдельно от классического round-trip.

Граница этой статьи:

В зоне этой статьиВынесено в соседние заметки
Сравнение REST, gRPC, GraphQL; выбор подхода; что фиксировать в спецификацииФорматы контрактов OpenAPI, Protobuf, GraphQL SDL — 03.05.03 Спецификации контрактов (OpenAPI, AsyncAPI, Protobuf)
Синхронный request–responseАсинхронные каналы, события, polling — 03.05.04 Асинхронное взаимодействие (очереди, Kafka, Events)
Подход как слой интеграцииАрхитектура интеграции (точка-точка, ESB, API-led) — 03.05.01 Виды интеграции (точка-точка, ESB, API-led)
Теория HTTP и семантика REST07.02 Принципы работы HTTP, REST, SOAP
Практика ручной проверки API07.02 Работа с API (практика)
Детали REST + OpenAPI03.05.02 REST и OpenAPI спецификации
Углублённо gRPC и GraphQL как контрактное программирование03.05.04 Контрактное программирование и протоколы (gRPC, GraphQL)
OAuth2, JWT, threat model, mTLS03.05.05 Безопасность API
Детали rate limiting, pagination как NFR03.06.03 Rate Limiting — управление пропускной способностью, 08.02 Нефункциональные требования (НФТ) — классификация и стандарты
sequenceDiagram
    participant Client as Клиент
    participant API as API (REST / gRPC / GraphQL)
    participant Backend as Backend / БД

    Client->>API: Запрос (синхронный, unary)
    Note over Client,API: Клиент ждёт ответ или таймаут
    API->>Backend: Обработка
    Backend-->>API: Данные / ошибка
    API-->>Client: Ответ (2xx / 4xx / 5xx или gRPC status)

Подход к API — лишь один слой интеграционного интерфейса. Вместе с ним в 03.01.04 Интерфейсы и интеграционные взаимодействия вы описываете форматы сообщений, политики безопасности, SLA и идентификаторы корреляции.

2. Ключевые понятия

Синхронный вызов и API-контракт

API (Application Programming Interface, программный интерфейс приложения) — формальный контракт между системами: операции, структуры данных, коды ошибок, правила аутентификации. В синхронной модели контракт определяет один запрос → один ответ (или явный таймаут/ошибку сети).

Критерии, по которым на проекте отличают синхрон от асинхронного канала:

  • Клиент не продолжает основной сценарий без ответа (или без явного fallback).
  • Нет промежуточного буфера доставки (очередь, топик) между запросом и ответом в рамках одного логического вызова.
  • SLA по latency задаётся на один round-trip, а не на end-to-end процесс.

Пограничный случай: в ESB-ландшафтах синхронный request–reply через message broker (клиент ждёт ответ в том же сеансе, но транспорт — очередь) формально sync для вызывающего, но архитектурно ближе к модели интеграции через шину — фиксируйте это явно в матрице потоков.

Webhooks и callbacks — исходящий HTTP POST партнёру после события: инициатор не ждёт ответ в своём пользовательском сценарии (хотя HTTP-вызов технически request–response). Это не классический sync API из scope статьи; длинные процессы с опросом статуса или callback — см. 03.05.04 Асинхронное взаимодействие (очереди, Kafka, Events).

Доменное событие как триггер sync-вызова — частый паттерн в событийной архитектуре: CRM публикует «заказ создан», Billing синхронно вызывает сервис расчёта в рамках обработчика. Канал остаётся request–response, хотя инициатор — реакция на событие; в матрице потоков фиксируйте и триггер, и тип канала отдельно.

REST (Representational State Transfer)

REST — архитектурный стиль, а не единый стандарт «REST API». Для аналитика важны не все ограничения Fielding, а то, что попадает в контракт:

  • Ресурсы с URI (/orders/{id}) и HTTP-методы с семантикой операций (GET — чтение, POST — создание, PUT/PATCH — изменение, DELETE — удаление).
  • Представления — JSON/XML как снимок состояния ресурса; статус-коды HTTP — сигнал успеха или ошибки.
  • Идемпотентность методов — GET, PUT, DELETE безопасны для повтора; POST — нет, если не задокументирован Idempotency-Key.

Детали HTTP-семантики, кэширования, conditional requests и multipart — в 07.02 Принципы работы HTTP, REST, SOAP; контракт de facto описывают в OpenAPI — 03.05.03 Спецификации контрактов (OpenAPI, AsyncAPI, Protobuf) и 03.05.02 REST и OpenAPI спецификации.

gRPC (Google Remote Procedure Call)

gRPC — фреймворк удалённого вызова процедур (RPC) с контрактом в Protocol Buffers (protobuf). Транспорт — HTTP/2, сериализация — бинарная (контекст — 07.07 Сетевые основы (подсети, протоколы и маршрутизация)).

В scope статьи — unary: один запрос, один ответ. Streaming-режимы (server/client/bidirectional) — полусинхронные сессии; на диаграммах помечайте отдельно. Структура .proto (service, rpc, messages) — 03.05.03 Спецификации контрактов (OpenAPI, AsyncAPI, Protobuf); углублённо — 03.05.04 Контрактное программирование и протоколы (gRPC, GraphQL).

Сильные стороны для SA: строгая типизация, contract-first, генерация клиентов. Для браузера и внешних партнёров обычно нужен grpc-web или API-gateway с трансляцией в HTTP/JSON.

GraphQL

GraphQL — язык запросов и runtime: одна HTTP-точка, схема (schema) как контракт (types, queries, mutations). Клиент задаёт форму ответа — снижается over-fetching; тот же эффект частично даёт BFF + узкие REST-endpoint'ы.

Для спецификации фиксируйте: resolver → backend-сервис, лимиты сложности запроса, поддержку batching. Mutations — синхронные изменения; subscriptions (WebSocket) — вне классического request–response. Governance схемы — 03.05.04 Контрактное программирование и протоколы (gRPC, GraphQL).

Частичный успех: HTTP 200 + блок data и errors[] одновременно — отдельный сценарий приёмки; клиент должен обрабатывать оба блока, в отличие от REST (код 4xx/5xx) и gRPC (status ≠ OK).

Сравнение для принятия решения

КритерийRESTgRPCGraphQLЧто зафиксировать в SRS/NFR
Модель контрактаРесурсы + HTTP-семантикаService + rpc + messagesSchema: types, queries, mutationsСсылка на machine-readable контракт как источник правды
Типичный потребительБраузер, B2B, legacyМикросервисы backend-to-backendBFF, SPA, агрегирующий слойКласс потребителя → выбор auth и SLA
КэшированиеHTTP-кэш, ETagНа уровне приложенияОграничено; complexity limitsПолитика кэша или явное «без кэша»
ВерсионированиеURL, заголовкиСовместимость полей в protoDeprecate полей в схемеПолитика breaking changes — 03.05.07 Управление версионированием API и жизненным циклом
Контракт ошибокHTTP-код + RFC 7807gRPC status + detailserrors[], частичный успехТаблица кодов/типов + сценарии retry
Отладка без toolingcurl, Postmangrpcurl, reflectionGraphiQLНужен ли sandbox/мок для приёмки

3. Как применяется в работе аналитика

Фиксация подхода в архитектурном контексте

На диаграмме контекста и при декомпозиции для каждого интеграционного потока зафиксируйте:

  • Кто вызывает кого (внутренний/внешний потребитель).
  • Подход (REST / gRPC / GraphQL) и формат payload — см. 07.03 Основы XML, JSON, YAML.
  • Синхронный vs асинхронный канал — не смешивайте на одной стрелке без пояснения.
  • SLA: latency (p95), availability, допустимые таймауты и retry.

Пример строки матрицы интеграций. Колонка «Триггер» — что инициирует вызов (событие, действие пользователя, расписание); триггер ≠ тип канала: «sync-вызов по событию» означает, что обработчик доменного события ждёт ответ в том же потоке, а не что канал асинхронный.

ИсточникПотребительПодходОперацияТриггерSLA latency
CRMBillinggRPCOrderService.CreateInvoiceсоздание заказа (sync-вызов по событию из 03.05.06 Event-Driven Architecture)< 500 ms
Mobile AppBFFGraphQLquery orderDetailsдействие пользователя< 800 ms
PartnerPublic APIRESTPOST /v1/shipmentsзапрос партнёра, до 100 rps< 1 s

Цепочки синхронных вызовов и latency budget

Типичная цепочка: UI → BFF → сервис A → сервис B. На sequence diagram указывайте не только SLA одного hop, но и суммарный e2e-бюджет:

  1. Задайте end-to-end p95 для сценария (например, 1,2 s для экрана заказа).
  2. Распределите бюджет по hop'ам — каждый участник цепочки получает долю с запасом на сеть и сериализацию; сумма hop'ов ≤ e2e.
  3. Timeout вызывающей стороны на hop N должен покрывать worst-case downstream на этом hop с учётом retries: timeout(A→B) ≥ p99(B) × (1 + число retry) + запас на сеть. Пример: p95 сервиса B = 400 ms, допускается 2 retry → timeout A не может быть 400 ms — нужен запас под три попытки (≈ 1,2 s + overhead).
  4. Timeout на hop N при этом ≤ оставшемуся e2e-бюджету после предыдущих hop'ов — иначе цепочка «съест» SLA экрана.

Не путайте: SLA downstream — обещание сервиса; timeout клиента — сколько вызывающий готов ждать на этом hop. Timeout обычно ≥ SLA downstream (с запасом на retry), но ≤ доля e2e для данного участка.

При превышении бюджета — сокращение цепочки (агрегация в BFF), кэш или переход на асинхронный канал.

Моделирование на диаграммах поведения

На sequence diagram явно указывайте тип вызова и синхронное ожидание:

  • REST: GET /orders/{id}, POST /orders + ожидание 200/201/4xx.
  • gRPC: OrderService.GetOrder(request) + gRPC status OK / NOT_FOUND (unary).
  • GraphQL: query GetOrder { order(id: ...) { ... } } + блок errors в JSON-ответе; отдельный alt-поток для частичного успеха (200 + data + errors).

Для прецедентов добавьте альтернативные потоки: таймаут, 503, retry (только для идемпотентных операций — GET/PUT/DELETE или POST с Idempotency-Key), fallback на кэш или асинхронный сценарий.

Связь с моделью данных

Каждое поле запроса и ответа трассируйте к логической модели и словарю данных: тип, обязательность, источник истины, правила преобразования.

ПодходЧто включать в спецификацию интерфейса
RESTТаблица endpoints; ссылка на OpenAPI; маппинг JSON-полей на сущности
gRPCПеречень services, rpc, messages, enum из .proto; коды gRPC status
GraphQLФрагмент схемы (types, queries, mutations); какой resolver читает какой backend

При GraphQL или BFF критично согласовать источник истины для каждого поля: одно поле в схеме может агрегировать данные из нескольких сервисов — это должно быть видно в спецификации, иначе расходится с ER-моделью.

Выбор подхода: практические критерии

Значимое решение оформляйте в ADR: контекст, альтернативы, последствия для потребителей и NFR. Breaking change в контракте согласуйте по процессу из 03.05.07 Управление версионированием API и жизненным циклом и 02.05.05 Жизненный цикл требования — до правки OpenAPI/proto/schema, а не после релиза.

REST + OpenAPI — когда:

  • публичный или партнёрский API с широкой аудиторией и ожиданием «стандартного HTTP»;
  • простые CRUD-операции над ресурсами;
  • нужна максимальная совместимость с HTTP-экосистемой и legacy;
  • gRPC/GraphQL снаружи допустимы через API gateway с трансляцией в REST/JSON.

gRPC — когда:

  • низкая задержка и высокая пропускная способность между внутренними сервисами;
  • нужен строгий contract-first и генерация кода из .proto;
  • unary покрывает сценарий; streaming — осознанное расширение контракта.

GraphQL — когда:

  • агрегирующий слой (BFF, публичный или внутренний) обслуживает UI с разными наборами полей (web, mobile);
  • over-fetching широких REST-ресурсов создаёт измеримую проблему, а BFF с узкими endpoint'ами нецелесообразен;
  • команда готова к governance схемы.

Если сценарий длится секунды и минуты (оркестрация, комплаенс-проверки), не растягивайте синхронный вызов: используйте 202 Accepted + polling/callback/webhook, либо асинхронный канал.

flowchart TB
    subgraph choice [Выбор подхода]
        Q1{Внешний / публичный API?}
        Q2{Нужна агрегация полей под UI?}
        Q5{Внутренний BFF / агрегирующий слой?}
        Q3{Низкая latency между сервисами?}
        Q4{Прямой HTTP без gateway?}
    end
    Q1 -->|да| Q2
    Q1 -->|нет, внутренний контур| Q5
    Q2 -->|да| GraphQL
    Q2 -->|нет| Q4
    Q4 -->|да| REST
    Q4 -->|нет: gRPC/GraphQL за gateway| GW[Gateway → REST/JSON наружу]
    Q5 -->|да| GraphQL
    Q5 -->|нет, прямой service-to-service| Q3
    Q3 -->|да, unary sync| gRPC
    Q3 -->|нет| REST

Нефункциональные требования: чеклист для спецификации

В спецификации интерфейса зафиксируйте минимум, без дублирования смежных статей — детали безопасности в 03.05.05 Безопасность API, классификация NFR в 08.02 Нефункциональные требования (НФТ) — классификация и стандарты, rate limiting в 03.06.03 Rate Limiting — управление пропускной способностью:

  • Аутентификация и авторизация — механизм на уровне контракта (OAuth2, JWT, API Key; gRPC metadata, mTLS).
  • Rate limiting и pagination — есть/нет, формат (REST: cursor/offset; GraphQL: connections).
  • Идемпотентность — REST: семантика GET/PUT/DELETE (безопасный retry) vs POST + Idempotency-Key; gRPC: ключ в metadata или документированная семантика unary-вызова; GraphQL: уникальные input id, dedup на сервере.
  • Таймауты и retry — retryable-коды (429, 503 + Retry-After); на каждом hop: timeout ≥ worst-case downstream × (1 + retries), сумма hop'ов ≤ e2e-бюджет (см. раздел выше).
  • Observability — correlation id / trace id (REST: заголовки; gRPC: metadata; GraphQL: extensions).
  • Версионирование — политика breaking changes: 03.05.07 Управление версионированием API и жизненным циклом.

Полный NFR-раздел удобно оформить по 10.01.12 Шаблон нефункциональных требований (NFR).

Артефакты, которые вы отдаёте команде

Минимальный набор для синхронного интерфейса (связь с форматами требований):

  1. Таблица операций — имя, method/query/rpc, вход, выход, коды ошибок, идемпотентность.
  2. Machine-readable контракт (OpenAPI / .proto / GraphQL SDL) как единственный источник правды; таблица в Confluence — производная, со ссылкой на репозиторий контракта.
  3. Матрица интеграций — система → система, подход, объём, SLA, latency budget для цепочек.
  4. Критерии приёмки — воспроизводимые сценарии по 02.04.02 Критерии приёмки (Acceptance Criteria); проверка на стенде — 07.02 Работа с API (практика); для REST — 10.01.04 Шаблон спецификации REST API.
  5. Contract / consumer-driven тесты (Pact и аналоги) — мост между контрактом и V&V / 08.03 Тестирование требований (статическое тестирование); в SRS зафиксируйте роль аналитика как владельца контракта (согласование breaking change, актуальность спецификации), а consumer/provider — ответственность команд разработки.

4. Типовые ошибки и ограничения

Ограничения подходов

REST:

  • «REST на бумаге» vs фактический RPC через POST /doSomething — нарушается единообразие интерфейса, усложняется кэширование и документирование.
  • Over-fetching и under-fetching — частично решается BFF и узкими ресурсами, не только GraphQL.
  • Версионирование без дисциплины — расхождение URL, заголовков и тела между средами.

gRPC:

  • Высокий порог для внешних партнёров и аналитиков без специализированного tooling.
  • Бинарный контракт усложняет ручную отладку; нужны grpcurl, reflection, сгенерированная документация.
  • Для браузера и части legacy — обязателен gateway; это отдельный компонент в архитектуре.
  • Streaming в контракте ≠ «ещё один sync endpoint» — иная модель таймаутов и backpressure.

GraphQL:

  • Тяжёлые запросы — глубокая вложенность, N+1 на resolver'ах; governance — в 03.05.04 Контрактное программирование и протоколы (gRPC, GraphQL).
  • Сложность HTTP-кэширования — кэш на уровне CDN/прокси работает иначе, чем у REST GET.
  • Размывание ответственности: frontend может «собрать» запрос, который неожиданно нагружает backend.
  • Subscriptions — отдельная инфраструктура (WebSocket), не путать с простым синхронным query/mutation.

Типичные ошибки аналитика

ОшибкаПоследствиеЧто делать
Синхронный API для длинного процессаТаймауты, блокировка UI, потеря транзакций202 + async, очередь, polling, webhook
Нет контракта ошибокНесогласованная обработка на клиентахREST: RFC 7807; gRPC: status + details; GraphQL: errors[] и сценарий частичного успеха
Таблица в Confluence вместо OpenAPI/protoУстаревшая спецификация, расхождение со стендомMachine-readable контракт в репозитории — источник правды
GraphQL «на всё» без лимитовДеградация productionComplexity budget, persisted queries, review схемы
Игнорирование идемпотентности POST/mutationДубликаты при retryIdempotency-Key (REST), metadata/input id (gRPC/GraphQL)
Разные модели в REST и gRPC без маппингаРасхождение с ER и словарём данныхЕдиная логическая модель, явный mapping
Протокол выбран «модно», без NFRНе выполняются latency и availabilityКритерии выбора + ADR + нагрузочные допущения
Не указаны таймауты и budget на sequence diagramНеверные ожидания интеграцииTimeout/retry по hop, e2e-budget; circuit breaker — 03.06.01 Архитектурные паттерны распределённых систем
Путаница webhook / события с sync APIНеверная модель ожиданий клиентаWebhook — исходящее уведомление; sync по событию — обработчик ждёт ответ; см. 03.05.06 Event-Driven Architecture

Синхронный вызов не заменяет согласованность данных между системами: при сбое после ответа «успех» нужны компенсирующие действия или асинхронное подтверждение — это предмет асинхронных паттернов и 03.06.01 Архитектурные паттерны распределённых систем.

Связи с другими разделами базы

Источники и дополнительные материалы

Книги и диссертации

Стандарты и спецификации