Интеграция систем через webhook или обратный вызов
Что такое Вебхук?
Вебхук — это механизм асинхронной интеграции, который позволяет одной системе уведомлять другую о произошедшем событии с помощью HTTP-запроса.
Этот технический подход основан на принципе обратного вызова, где сервер (источник события) сам инициирует взаимодействие с клиентом (системой, ожидающей уведомления).
Сравнение подходов к интеграции
В событийно-ориентированной архитектуре часто используются очереди сообщений, но они могут быть избыточными или неуместными, особенно при интеграции с внешними системами, не работающими с брокерами.
Polling (периодический опрос)
Классическая синхронная схема предполагает, что клиентская система периодически опрашивает сервер, отправляя запросы типа «А что-нибудь произошло?». Это создаёт избыточную нагрузку на сеть и сервер, снижая производительность и создавая риск DDoS-атак.
Webhook (обратный вызов)
Вебхук предлагает альтернативу: клиентская система регистрирует свой API-метод у сервера, говоря: «Когда произойдет событие, вызови мой API-метод». Таким образом, сервер сам выступает в роли инициатора вызова, отправляя уведомление клиенту, когда событие действительно происходит. Это решение позволяет избежать ненужного трафика и оптимизировать взаимодействие.
Теперь давайте рассмотрим это на более живых примерах.
Примеры работы с webhooks
Некоторые сервисы позволяют настроить webhooks прям из интерфейса.
Вебхуки GitHub
Например, популярный сервис GitHub в настройках репозитория позволяет добавить любое количество веб-хуков. Для каждого указывается вызываемый URL, формат полезной нагрузки, а также можно выбрать, при каких событиях, он сработает.

Вебхуки ЮКасса
Другой вариант — это популярный платежный сервис ЮКасса. У ЮКассы есть прекрасная исчерпывающая документация по использованию вебхуков.
Входящие уведомления — Прием оплаты API ЮKassa (yookassa.ru)
Событие в ЮKassa — изменение статуса объекта. Вы можете отслеживать события платежей, возвратов, выплат и сделок. В случае, если применяется базовая аутентификация, вебхуки настраиваются через интерфейс личного кабинета вручную. А в случае, если клиент использует OAuth аутентификацию ЮКассы, она предоставляет API для программной конфигурации вебхуков.
То есть, чтоб сообщить ЮКассе “шли мне уведомление о таком-то событии туда-то“, клиентская сторона вызывает соответствующий метод API, где сообщает свой URL для обратного вызова, и тип событий:
curl https://api.yookassa.ru/v3/webhooks \
-X POST \
-H 'Authorization: Bearer <oauth_token>' \
-H 'Idempotence-Key: <Ключ идемпотентности>' \
-H 'Content-Type: application/json' \
-d '{
"event": "payment.succeeded",
"url": "https://www.example.com/notification_url"
}'
Проверка работоспособности вебхука
Если вы хотите проверить, как работает вебхук, но у вас еще нет принимающей стороны и нечего передать в качестве URL для обратного вызова, можно воспользоваться специальным сервисом на сайте Webhook.site — Test, transform and automate Web requests and emails
Здесь нужно сгенерировать уникальный URL, указать его в качестве URL для обратного вызова в том сервисе, с которого вы хотите получать уведомления. И ждать. Когда произойдет событие, на сайте Webhook.site вы увидите в разделе Requests подробности вызова и содержимое тела запроса.
Второй вариант тестирования вебхука “на коленке“ — это создать телеграмм-бота, и указать в качестве URL обратного вызова — URL метода для отправки сообщения в телеграмм-бот, вида https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={chat_id}&text={txt}, где вместо переменных {TOKEN} и {chat_id} нужно указать токен и идентификатор телеграмм-бота, а также текст сообщения.
Пример применения вебхука
Итак, еще раз подведем итог, и посмотрим на диаграммах последовательности, как выглядит интеграция систем с использованием вебхука и без.
Например, клиент оплачивает заказ в интернет магазине через платежную систему. Интернет-магазину нужно подтвердить платеж, чтоб отправить заказ в работу. Но процесс оплаты может занять от нескольких минут до нескольких часов.
И первым вариантом решения этой проблемы является периодическая отправка GET-запросов, чтоб узнать статус платежа.
Это долго, и все становятся резко занятыми. Интернет-магазин тем, что постоянно спрашивает. А платежная система тем, что постоянно обрабатывает входящие запросы статуса.

@startuml title Пример Polling participant "Интернет-магазин" as Service participant "Платежная система" as ExternalService #lightgreen activate Service Service -> ExternalService: провести платеж \nHTTP POST /payment activate ExternalService ExternalService --> ExternalService: Принять платеж в обработку ExternalService -> Service: 201 Created deactivate ExternalService Service -> ExternalService: узнать статус \nHTTP GET /payment/status activate ExternalService ExternalService -> Service: статус платежа "в работе" deactivate ExternalService Service -> ExternalService: узнать статус \nHTTP GET /payment/status activate ExternalService ExternalService -> Service: статус платежа "в работе" deactivate ExternalService Service -> ExternalService: узнать статус \nHTTP GET /payment/status activate ExternalService ExternalService -> Service: статус платежа "в работе" deactivate ExternalService ... ExternalService -> ExternalService: перевести деньги со счета на счет activate ExternalService deactivate ExternalService ... Service -> ExternalService: узнать статус \nHTTP GET /payment/status activate ExternalService ExternalService -> Service: статус платежа "выполнен" deactivate ExternalService Service --> Service: Обновить статус платежа в БД deactivate Service @enduml
Вместо этого можно просто дожидаться уведомления от платежной системы о том, что платеж прошел. В этом случае все занимаются своим делом и никто никого не бомбит лишним трафиком. Когда платеж будет проведен (либо отклонен), платежная система вызовет REST API метод интернет-магазина, и тот обновит статус заказа.

@startuml title Пример Webhook participant "Интернет-магазин" as Service participant "Платежная система" as ExternalService #lightgreen activate Service Service -> ExternalService: провести платеж \nHTTP POST /payment activate ExternalService ExternalService --> ExternalService: Принять платеж в обработку ExternalService -> Service: 201 Created deactivate ExternalService deactivate Service ... ExternalService --> ExternalService: Перевести деньги со счета на счет activate ExternalService ExternalService -> Service: вызов вебхука\nPOST /payment/status activate Service Service --> Service: Обновить статус платежа в БД Service --> ExternalService: 200 OK deactivate Service deactivate ExternalService @enduml
Таким образом, по сути с помощью синхронных вызовов реализуется асинхронная интеграция между системами.
Другие статьи
Use Case vs. User Story: как выбрать правильный инструмент для проекта
Оба этих инструмента помогают командам лучше понять потребности пользователей и определить функциональные требования к продукту…
Влияние моделей ACID и BASE на выбор хранилища данных
Эти два подхода определяют степень консистентности данных и надежности системы…
NoSQL базы данных: основные виды и их отличия для системного аналитика
Когда речь заходит о хранении данных, есть два основных подхода — реляционные и нереляционные базы данных.