В интеграциях корпоративных систем часто спорят не о том, как связать системы, а о том, чем именно их связать: REST API, webhook или брокером сообщений.

На практике универсального ответа нет. REST удобен, когда одной системе нужен ответ другой прямо сейчас. Webhook — когда система должна сообщить о произошедшем событии. Брокер — когда сообщения нужно доставлять асинхронно, независимо от доступности отдельных потребителей.

Ошибка обычно возникает не при выборе конкретной технологии, а когда один механизм пытаются использовать для всех сценариев.

Разберём три подхода на практических примерах и посмотрим, где проходит граница между ними.

REST: когда одна система прямо спрашивает другую

Сайт запрашивает у 1С остаток товара и ждёт ответ здесь и сейчас, прежде чем показать карточку товара покупателю.

Это классический сценарий REST API: одна система отправляет HTTP-запрос, другая его обрабатывает и возвращает ответ.

Условно:

Сайт → GET /products/123/stock → 1С → остаток: 7 → Сайт

Главное преимущество такого подхода — предсказуемость. Отправили запрос, получили ответ или ошибку и можем сразу продолжить обработку.

REST хорошо подходит, когда:

•           ответ нужен непосредственно в момент выполнения операции;

•           запрос относительно лёгкий;

•           результат нужен только инициатору запроса;

•           допустима зависимость от доступности системы, к которой обращаемся.

Например:

•           проверить остаток товара;

•           получить карточку клиента;

•           рассчитать стоимость доставки;

•           проверить доступность услуги;

•           авторизовать пользователя.

Где REST начинает создавать проблемы

Представим интернет-магазин, который при оформлении каждого заказа синхронно обращается к 1С.

Пока 1С отвечает быстро, всё работает нормально. Но если она под нагрузкой начинает отвечать по несколько секунд, сайт вынужден ждать. Если 1С временно недоступна, приложению приходится самостоятельно решать, что делать: повторять запрос, показывать ошибку, ставить операцию в очередь или использовать резервный сценарий.

REST сам по себе не означает, что система обязательно «зависнет». Таймауты, повторные попытки (retries), circuit breaker, асинхронная обработка и другие механизмы позволяют снизить последствия таких сбоев.

Проблема в другом: при синхронной интеграции доступность одной системы начинает влиять на выполнение операции в другой.

Если это нормально для конкретного сценария — REST остаётся простым и хорошим выбором.

Webhook: когда система сама сообщает о событии

Платёжный сервис не заставляет ваш сервер постоянно спрашивать:

«Оплата прошла? А сейчас? А сейчас?»

Вместо этого он сам отправляет HTTP-запрос на заранее заданный endpoint, когда происходит событие.

Например:

Платёжная система → POST /webhooks/payment → Ваш сервер

В запросе может быть информация о платеже, его статусе и идентификаторе события.

Это webhook: система-источник сама сообщает другой системе, что что-то произошло.

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

•           платёж проведён;

•           статус доставки изменился;

•           документ подписан;

•           заказ отменён;

•           пользователь подтвердил действие.

Главное преимущество webhook перед постоянным polling — не нужно регулярно спрашивать систему об изменениях. Событие отправляется тогда, когда оно произошло.

Но webhook — это не гарантия доставки

И здесь появляется одна из самых частых проблем.

Допустим, платёжный сервис отправил webhook, но ваш сервер в этот момент:

•           перезапускается;

•           перегружен;

•           находится на деплое;

•           временно недоступен из-за сетевой ошибки.

Если отправитель поддерживает повторную доставку, он не получит успешный HTTP-ответ и отправит то же событие ещё раз.

Поэтому обработчик webhook должен быть рассчитан на повторную доставку.

Обычно для этого:

1.         у события есть уникальный идентификатор;

2.         сервер проверяет, обрабатывалось ли событие раньше;

3.         повторное событие не приводит к повторному выполнению бизнес-операции.

Например, если webhook с event_id=12345 уже обработан, второй такой же запрос не должен повторно создавать заказ. Проверку идентификатора и изменение данных нужно согласовать так, чтобы два одновременных запроса тоже не выполнили операцию дважды.

Это называется идемпотентной обработкой.

Бывает и обратная ситуация: попытки исчерпаны или отправитель вообще не повторяет запросы — и событие можно пропустить. Для критичных операций полезна сверка с источником через его API: например, периодически сравнивать статусы оплат и восстанавливать пропущенные события.

Также для webhook стоит предусмотреть проверку подписи запроса, таймауты, журналирование и понятную стратегию повторной обработки ошибок.

Когда выбирать webhook

Webhook хорошо подходит, когда:

•           источник события находится вне вашей системы;

•           вам нужно получать уведомления о событиях;

•           реакция может происходить асинхронно;

•           вам не нужно постоянно опрашивать внешний сервис.

Например, платёжная система сообщает об успешной оплате, после чего ваше приложение запускает дальнейшую обработку заказа.

Message Broker: когда систем становится много

Теперь представим заказ на складе.

После его создания нужно:

•           обновить остаток;

•           передать информацию в CRM;

•           отправить уведомление клиенту;

•           передать данные в аналитическую систему;

•           запустить дальнейшую обработку на складе.

Можно построить прямые интеграции:

Система заказов → CRM
Система заказов → склад
Система заказов → уведомления
Система заказов → BI

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

Вместо этого можно использовать брокер сообщений:

                          → CRM
Система заказов → Broker  → склад
                          → уведомления
                          → BI

Система заказов публикует событие, например order.created.

Дальше заинтересованные сервисы получают его независимо друг от друга.

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

В качестве инфраструктуры обмена сообщениями могут использоваться, например, RabbitMQ или Kafka. В корпоративной среде функции обмена сообщениями также могут быть частью более широкой интеграционной или ESB-платформы.

Главный выигрыш — развязка систем

Системе заказов больше не нужно синхронно ждать ответа CRM при публикации события.

Если CRM временно недоступна, сообщение может остаться в инфраструктуре обмена и быть обработано позже — если такая модель доставки настроена в используемой системе. При повторной доставке брокер может передать сообщение ещё раз, поэтому потребителям тоже нужна идемпотентная обработка.

Это позволяет разделить:

производителя события
и
потребителей события.

Но за это приходится платить сложностью.

Появляется дополнительная инфраструктура, которую нужно:

•           развернуть;

•           мониторить;

•           масштабировать;

•           резервировать;

•           обновлять;

•           контролировать с точки зрения безопасности.

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

REST, Webhook или Broker: как выбрать

Упрощённое правило можно свести к трём вопросам.

1. Мне нужен ответ прямо сейчас?

Да → REST.

Например, нужно узнать остаток товара перед тем, как показать его покупателю.

2. Другая система должна сообщить мне о событии?

Да → Webhook.

Например, платёжный сервис должен сообщить об успешной оплате.

3. Одно событие должны независимо обработать несколько систем?

Часто да → Message Broker, если получателям нужна независимая обработка, повторная доставка или буферизация.

Например, после создания заказа информацию одновременно должны получить склад, CRM, уведомления и аналитика.

Но есть важная оговорка: это не три взаимоисключающих варианта.

В реальном проекте они часто работают вместе.

Когда webhook и broker используются одновременно

Например, внешняя платёжная система отправляет webhook после успешной оплаты.

Первый участок интеграции может выглядеть так:

Платёжная система → Webhook → API вашего сервиса

API принимает событие, проверяет подпись и уникальность события, а затем публикует его во внутренний брокер:

Webhook → API → Message Broker

Успешный ответ отправителю следует возвращать после надёжного сохранения события. Если API вернул 200, а публикация в брокер не удалась, событие может потеряться. Один из способов закрыть этот разрыв — сначала сохранить событие в базе, а затем передать его в брокер отдельным процессом. Если одновременно меняются бизнес-данные, событие и изменения можно записать в одной транзакции по схеме transactional outbox. Публикация при этом всё равно может повториться, поэтому потребителям нужна идемпотентность.

Дальше уже внутренние сервисы подписываются на нужные события:

                 → Сервис заказов
Message Broker   → CRM
                 → Уведомления
                 → Аналитика

В таком варианте webhook решает одну задачу — доставляет событие от внешней системы внутрь вашей инфраструктуры.

А брокер решает другую — распределяет событие между внутренними потребителями и снижает связанность между ними.

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

А если событие нужно только одной системе?

Тогда брокер может оказаться избыточным.

Допустим, сервис доставки отправляет webhook об изменении статуса заказа, а обработать его должен только один небольшой сервис.

Поднимать отдельную брокерную инфраструктуру только ради этого события может быть неоправданно.

Webhook здесь проще:

Сервис доставки → Webhook → Ваш API

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

Не стоит добавлять распределённую инфраструктуру раньше, чем появляется реальная потребность в ней.

Что выбрать: короткая шпаргалка

Сценарий

Подход

Нужно получить ответ прямо сейчас

REST

Нужно выполнить операцию и сразу узнать результат

REST

Внешняя система сообщает о событии

Webhook

Нужно отказаться от постоянного polling

Webhook

Одно событие независимо обрабатывают несколько сервисов

Message Broker

Нужна буферизация при недоступности получателей

Message Broker с настроенным хранением сообщений

Нужна асинхронная обработка большого потока событий

Message Broker

Событие приходит извне, а внутри его обрабатывают несколько сервисов

Webhook + Message Broker

Где чаще всего ошибаются

Есть три типичные архитектурные ошибки.

Первая — использовать REST для всего.

Так появляются цепочки синхронных вызовов, где одна операция зависит сразу от нескольких сервисов.

Вторая — использовать webhook без идемпотентности.

Повторная доставка события становится причиной дублей или повторного выполнения бизнес-операции.

Третья — ставить брокер там, где достаточно обычного HTTP-запроса.

Брокер — не универсальное средство «сделать архитектуру надёжнее». Это дополнительная инфраструктура со своей стоимостью и сложностью.

Поэтому вопрос стоит формулировать не как:

«Что лучше — REST, webhook или Kafka?»

А как:

«Какой способ взаимодействия соответствует требованиям именно этого участка системы?»

Итог

REST, webhook и message broker решают разные задачи.

REST — когда нужно обратиться к другой системе и получить ответ.

Webhook — когда система должна сообщить о произошедшем событии через HTTP.

Message broker — когда события нужно обрабатывать асинхронно и независимо распределять между несколькими потребителями.

В зрелой архитектуре эти подходы не конкурируют друг с другом. Один и тот же процесс может использовать все три:

REST — для синхронного запроса данных,
Webhook — для получения события от внешней системы,
Broker — для дальнейшего распределения этого события внутри инфраструктуры.

Выбор зависит от того, нужен ли ответ сразу, кто инициирует обмен и что должно происходить при сбое одного из участников.

Комментарии (0)