Заметки бизнес-аналитика
Главная › Системный анализ

Интеграции и REST API

Способы интеграции

  • Файловый обмен — выгрузка и загрузка файлов (CSV, XML) по расписанию. Просто, но с задержкой.
  • Общая база данных — системы читают и пишут в одну БД. Быстро, но создаёт сильную связанность.
  • Удалённый вызов (API) — REST, SOAP, gRPC. Синхронный запрос–ответ.
  • Обмен сообщениями — через брокер (Kafka, RabbitMQ). Асинхронно, слабая связанность.

Синхронно или асинхронно

СинхронноАсинхронно
Как работаетОтправитель ждёт ответаОтправитель не ждёт, результат придёт позже или не нужен
ПлюсыПросто, сразу понятен результатУстойчивость к сбоям получателя, сглаживание пиков, слабая связанность
МинусыЕсли получатель недоступен — отказ; цепочки вызовов медленныеСложнее отладка, нужна обработка дублей и порядка
ПримерПроверка остатка товара при добавлении в корзинуОтправка заказа в 1С, рассылка уведомлений, скоринг заявки

HTTP: методы

МетодНазначениеБезопасныйИдемпотентный
GETПолучить ресурсдада
POSTСоздать ресурс или запустить действиенетнет
PUTПолностью заменить ресурснетда
PATCHЧастично изменить ресурснетне гарантируется
DELETEУдалить ресурснетда

Безопасный метод не меняет состояние сервера. Идемпотентный — повтор того же запроса оставляет сервер в том же состоянии, что и один запрос. Коды ответа при этом могут отличаться: второй DELETE вернёт 404, но ресурс удалён один раз.

PUT vs PATCH: PUT присылает ресурс целиком и заменяет его (неуказанные поля сбрасываются); PATCH присылает только изменяемые поля.

HTTP: коды ответов

  • 2xx — успех: 200 OK, 201 Created (создан ресурс, обычно с заголовком Location), 202 Accepted (принято в асинхронную обработку), 204 No Content.
  • 3xx — перенаправление: 301, 302, 304 Not Modified.
  • 4xx — ошибка клиента: 400 Bad Request (невалидные данные), 401 Unauthorized (не аутентифицирован), 403 Forbidden (нет прав), 404 Not Found, 409 Conflict (конфликт состояния, дубль), 422 Unprocessable Entity (бизнес-валидация), 429 Too Many Requests.
  • 5xx — ошибка сервера: 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout.

Проектирование REST API: пример корзины

Принципы: URL обозначает ресурс (существительное, обычно во множественном числе), действие задаётся методом, ответы в JSON, ошибки — понятными кодами и телом.

GET    /carts/{cartId}                   — получить корзину
POST   /carts/{cartId}/items             — добавить товар   → 201
PATCH  /carts/{cartId}/items/{itemId}    — изменить количество → 200
DELETE /carts/{cartId}/items/{itemId}    — удалить товар     → 204
POST   /orders                           — оформить заказ из корзины → 201
       Idempotency-Key: 7f3c...          (защита от двойного заказа)
GET    /orders?status=PAID&page=2&size=20 — список с фильтром и пагинацией
POST /carts/42/items
{ "productId": 1001, "quantity": 2 }

201 Created
{ "itemId": 7, "productId": 1001, "quantity": 2, "price": 1490.00 }

409 Conflict
{ "code": "OUT_OF_STOCK", "message": "Недостаточно товара на складе", "available": 1 }

Что описать в требованиях к методу: назначение и кто может вызывать, URL и метод, заголовки (авторизация, Idempotency-Key), параметры и тело с типами и обязательностью, логика обработки и валидации, все варианты ответов с кодами и примерами, НФТ (время ответа, лимиты).

Идемпотентность POST

POST не идемпотентен: при обрыве связи клиент повторит запрос и создаст второй заказ. Решение — клиент генерирует Idempotency-Key и передаёт его в заголовке; сервер запоминает ключ и на повтор возвращает уже созданный результат, а не создаёт новый.

Другие протоколы

  • SOAP — протокол на XML со строгим контрактом WSDL. Встречается в банках, госсистемах, legacy.
  • gRPC — бинарный протокол поверх HTTP/2, контракт в Protobuf, поддерживает стриминг. Быстрый, для обмена между сервисами.
  • GraphQL — клиент сам указывает, какие поля вернуть.
  • Webhook — сервер сам вызывает URL клиента при событии (вместо постоянного опроса).
  • WebSocket — постоянное двустороннее соединение для real-time (чаты, котировки).
  • OpenAPI (Swagger) — стандарт описания REST API в YAML/JSON.

Брокеры сообщений

  • Producer публикует сообщения, consumer их читает. Они не знают друг о друге.
  • Очередь (point-to-point): каждое сообщение обрабатывает один потребитель. Топик (pub/sub): сообщение получают все подписчики.
RabbitMQKafka
МодельКлассические очереди, брокер сам раздаёт сообщения (push)Распределённый журнал, потребитель сам читает по смещению (pull)
После чтенияСообщение удаляетсяХранится заданное время, можно перечитать
Сильные стороныГибкая маршрутизация (direct, topic, fanout, headers), DLX, приоритетыОгромная пропускная способность, история событий, много независимых потребителей
ПорядокВ пределах очередиВ пределах партиции (по ключу)
Типичное применениеОчереди задач, уведомления, интеграция сервисовПотоки событий, аналитика, логи, event sourcing

Надёжность асинхронного обмена

Гарантии доставки

  • At most once — не больше одного раза; сообщение может потеряться.
  • At least once — минимум один раз; возможны дубли. Самый частый вариант на практике.
  • Exactly once — ровно один раз; сложно и дорого, работает только в границах одной системы.

Практическое правило: at least once + идемпотентный потребитель. Потребитель хранит ID обработанных сообщений и пропускает повторы.

Паттерны

  • Retry с экспоненциальной задержкой (1 с, 2 с, 4 с, 8 с…) и ограничением числа попыток. Повторять только временные ошибки (таймаут, 503, 429), а не 400.
  • DLQ (Dead Letter Queue) — очередь для сообщений, которые не удалось обработать за N попыток. Их разбирают вручную или переотправляют после исправления.
  • Transactional Outbox — проблема двойной записи: заказ сохранили в БД, а событие в брокер не отправилось. Решение: в той же транзакции записать событие в таблицу outbox, а отдельный процесс публикует его в брокер.
  • Circuit Breaker — если внешняя система постоянно падает, временно перестать её вызывать и сразу возвращать ошибку или запасной ответ, чтобы не копить зависшие запросы.
  • Корреляционный ID — сквозной идентификатор запроса во всех логах и сообщениях для поиска проблем.

Кейс: сайт → CRM → 1С

  1. Сайт синхронно создаёт заказ в своём сервисе заказов и сразу отвечает покупателю.
  2. Сервис заказов через outbox публикует событие OrderCreated в брокер.
  3. CRM и 1С подписаны на событие и обрабатывают его независимо. Если 1С недоступна, сообщения ждут в очереди.
  4. Потребители идемпотентны по orderId; после 5 неудачных попыток сообщение уходит в DLQ, дежурный получает алерт.
  5. Формат сообщения: eventId, eventType, occurredAt, version, данные заказа.

Вопросы для самопроверки

Чем 401 отличается от 403?

401 — система не знает, кто вы (нет токена или он недействителен). 403 — система знает, кто вы, но у вас нет прав на это действие.

Почему POST не идемпотентен и как с этим жить?

Каждый POST может создать новый ресурс, поэтому повтор после таймаута создаст дубль. Защита — ключ идемпотентности от клиента, уникальные ограничения в БД или проверка по бизнес-ключу.

Когда выбрать Kafka, а когда RabbitMQ?

Kafka — когда нужен поток событий большого объёма, хранение истории и несколько независимых потребителей. RabbitMQ — когда нужны очереди задач, сложная маршрутизация и обработка каждого сообщения ровно одним исполнителем.

Конспекты статей по теме

Подробные конспекты полезных статей. В конце каждого есть ссылка на оригинал и автора.