Fan-out: один вебхук, несколько сервисов, без каскада 500-х и потерь
Смотрим в тело запроса: один входящий хук не должен знать, кто его дальше ест. Приемник делает минимум работы — валидирует подпись, проверяет idempotency_key и кладет событие в очередь. Дальше уже fan-out: воркер читает одно событие и раскладывает его по нескольким downstream-сервисам.
Критичная деталь — не слать все синхронно из хендлера. Если один сервис подвис, вы ловите 5xx на ровном месте и теряете весь пайплайн. Правильнее так: ingress -> broker -> dispatcher -> service A/B/C. У каждого потребителя свой ретрай-политика, свой timeout и своя DLQ. Идемпотентность — это не роскошь, а база.
Метаданные прокидываем отдельно: event_id, source, created_at, correlation_id, retry_count. Сам payload не мутируем, иначе через третью интеграцию начнется археология. Если один из сервисов не нужен для конкретного типа события, режьте маршрут на этапе диспетчера, а не в коде подписчика.
Минимальный контракт выглядит так: { "event_id":"...", "type":"order.paid", "targets":["crm","billing","analytics"], "payload":{...} } Один хук, много потребителей, но одно правило неизменно: подтверждаем только прием в буфер, а не успешную доставку во все системы. Иначе fan-out превращается в fan-out of pain.
Автоматизация на вебхуках
@webhook_automation_hub_arb
Fan-out: один вебхук, несколько сервисов, без каскада 500-х и потерь
Этот пост опубликован в Telegram-канале Автоматизация на вебхуках. Подписаться можно по ссылке: @webhook_automation_hub_arb.