Интеграции и 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): сообщение получают все подписчики.
| RabbitMQ | Kafka | |
|---|---|---|
| Модель | Классические очереди, брокер сам раздаёт сообщения (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С
- Сайт синхронно создаёт заказ в своём сервисе заказов и сразу отвечает покупателю.
- Сервис заказов через outbox публикует событие
OrderCreatedв брокер. - CRM и 1С подписаны на событие и обрабатывают его независимо. Если 1С недоступна, сообщения ждут в очереди.
- Потребители идемпотентны по
orderId; после 5 неудачных попыток сообщение уходит в DLQ, дежурный получает алерт. - Формат сообщения:
eventId,eventType,occurredAt,version, данные заказа.
Вопросы для самопроверки
Чем 401 отличается от 403?
401 — система не знает, кто вы (нет токена или он недействителен). 403 — система знает, кто вы, но у вас нет прав на это действие.
Почему POST не идемпотентен и как с этим жить?
Каждый POST может создать новый ресурс, поэтому повтор после таймаута создаст дубль. Защита — ключ идемпотентности от клиента, уникальные ограничения в БД или проверка по бизнес-ключу.
Когда выбрать Kafka, а когда RabbitMQ?
Kafka — когда нужен поток событий большого объёма, хранение истории и несколько независимых потребителей. RabbitMQ — когда нужны очереди задач, сложная маршрутизация и обработка каждого сообщения ровно одним исполнителем.
Конспекты статей по теме
Подробные конспекты полезных статей. В конце каждого есть ссылка на оригинал и автора.
- Системный аналитик. Краткий гайд по профессии. Часть 1. Основы взаимодействия систем — Николай (nick_oldman)
- Общие принципы интеграций систем. SA для самых маленьких — lyosik
- Базовое проектирование и разработка требований к интеграции систем — Amelchenko
- Системный аналитик. Часть 4. Синхронные и асинхронные интеграции: REST, gRPC, Kafka, RabbitMQ — Николай (nick_oldman)
- 25 вопросов и ответов по REST API на собеседовании системного аналитика — Сергей Березин (SSP SOFT)
- Проектирование REST API: спорные вопросы с проектов и собеседований — Екатерина Ананьева (katherine_a, GetAnalyst)
- Как мы описываем требования к REST API для бэкенда в Confluence — Ирина Тикинева (Magnit Tech)
- Идемпотентный метод — глоссарий MDN — MDN Web Docs
- Асинхронная интеграция: что это такое и как её дружить — Виталий Якубин (публикация YuNastasiya, ITQ Group)
- Чем различаются Kafka и RabbitMQ: простыми словами — Павел Малыгин (trusted, Иннотех)
- Брокеры сообщений Kafka и RabbitMQ в реальной жизни — Александр Борецкий (Т1)
- Надёжная асинхронная коммуникация: повторы, дубликаты и dead letter queues — justwack