В интеграциях корпоративных систем часто спорят не о том, как связать системы, а о том, чем именно их связать: 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 Система заказов → склад Система заказов → уведомления Система заказов → 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
Нужно отказаться от постоянного pollingWebhook
Одно событие независимо обрабатывают несколько сервисов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 — для дальнейшего распределения этого события внутри инфраструктуры.

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