Программное обеспечение сегодня становится все более взаимосвязанным.

Вместо того, чтобы создавать что-то с нуля, сегодня все больше инженерных работ заключается в «соединении» сборных деталей вместе. Мы можем все больше и больше полагаться на сторонние сервисы: компании, которые предоставляют API — программный интерфейс — к которому другие системы подключаются и используют для таких сервисов, как платежи, электронная почта и т. д.

Это ускоряет разработку программного обеспечения: мы можем больше сосредоточиться на основе наших ценностных предложений вместо создания второстепенных (но все же необходимых) возможностей, таких как инфраструктура электронной почты и развертывание серверов. Эти вторичные компоненты можно делегировать внешним API.

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

Как мы должны прослушивать эти события?

Сначала давайте рассмотрим опрос – традиционный для систем способ предоставления возможностей обмена данными в режиме реального времени.

Опрос

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

Наш уютный книжный магазин по соседству.

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

Клиент отправляет HTTP-запрос на сервер для определенного ресурса,

и сервер отвечает на запрос.

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

Вскоре вы понимаете, что опросы (в данном случае ежедневные звонки в магазин) — это огромная трата.

Традиционные API-интерфейсы REST предназначены для случаев, когда вы хотите разрешить синхронное чтение или запись. Это далеко не оптимально, когда вы просто хотите, чтобы ваше приложение сообщалось, когда что-то изменилось, потому что это потребовало бы опроса через регулярные промежутки времени, а это просто не масштабируется.

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

По данным Zapier, 98,5 % запросов на опрос не возвращают никакой новой полезной информации.

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

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

Опрос — это не решение для работы в Интернете в режиме реального времени, это хак! Это должно заставить вашего внутреннего инженера съежиться.

Вебхуки

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

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

Когда появится новая информация,

поставщик событий веб-перехватчика отправит сообщение с этой информацией, выполнив запрос HTTP POST с полезной нагрузкой JSON:

И клиенты ответят, чтобы сообщить провайдеру, что сообщение было получено.

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

Веб-перехватчики можно рассматривать как обратные API.

Вебхуки в реальном мире

Кто использует вебхуки? Почти все.

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

Причины использовать вебхуки

Веб-перехватчики в 66 раз эффективнее традиционных опросов. В то время как только 1,5% запросов на опрос являются действенными, с веб-перехватчиками ожидаемая цифра приближается к 100%.

Тем самым вы можете:

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

Вебхуки также предлагают улучшенный пользовательский интерфейс. Веб-хуки — это более идиоматическое решение для получения программных обновлений в реальном времени от сторонних сервисов по сравнению с опросом каждые X минут.

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

Дизайн вебхука 101

Давайте посмотрим, как вы можете создавать свои веб-хуки. Использование вебхука состоит из трех основных этапов: настройка, подписки и уведомления.

Настраивать

Далее следует управлять самой подпиской веб-перехватчика как ресурсом REST. (Этот подход называется RESThooks.)

Как минимум, объект подписки на веб-перехватчик включает:

  • список названий событий
  • целевой URL
  • статус (вкл/выкл)

Наличие пользовательского интерфейса для взаимодействия с Subscriptions API — огромное благо для разработчиков.

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

Что в событии?

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

Каждому типу события нужны как минимум две вещи:

  • Имя (используйте точечный синтаксис существительное.глагол, IE: contact.create или lead.delete).
  • Шаблон полезной нагрузки (просто отразите представление из вашего стандартного API).

Полезная нагрузка, которую вы создаете для каждой записи в вашем REST API, будет точно соответствовать вашему API-представлению того же объекта. Это упрощает сопоставление ресурсов REST с ресурсами-ловушками и наоборот.

Многие поставщики веб-перехватчиков следуют соглашению об именах namespace.noun.verb для своих типов событий.

Отправка и доставка событий

Первый компонент, который требуется поставщику событий веб-перехватчика, — это Event Dispatch: механизм, указывающий в коде вашего приложения, что событие инициировано.

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

Например, встроенная функция notify(<my-event>) может отправить сообщение в вашу очередь сообщений.

defmodule MyApplication do
  def doSomething do
    # ...some code
    Events.notify(:myEventType, %{ data: 1 })
    # ...some more code
  end
end

Вам также нужна доставка событий: механизм для POST или иной доставки полезной нагрузки для каждого события в вашей очереди сообщений на соответствующий целевой URL-адрес для каждой соответствующей подписки.

Компонент доставки событий должен обрабатывать:

  • Компиляция и отправка комбинированной полезной нагрузки для ресурса-триггера и ресурса-ловушки.
  • Обработка ответов, таких как 410 Gone, и, при необходимости, повторная попытка подключения или другие ошибки 4xx/5xx.
  • Повторные попытки

Если вы знаете, что вам нужно масштабировать свое решение, используйте инструмент, специально разработанный для этого. Вы можете использовать масштабируемые решения для организации очередей с открытым исходным кодом, такие как RabbitMQ, или такой сервис, как Amazon Simple Queuing Service.

Таким образом, ваше взаимодействие ограничивается добавлением и удалением «сообщений», которые сообщают вам, какие веб-перехватчики вызывать. Как и в случае с очередью БД, вам нужен отдельный процесс для потребления элементов из очереди и отправки уведомлений. В дополнение к использованию инструмента, предназначенного для этой цели, правильная очередь также экономит ресурсы базы данных для того, что она делает лучше всего — предоставления данных вашему основному приложению.

Безопасность веб-перехватчика

Ключ к защите ваших веб-перехватчиков заключается в том, чтобы позволить клиентам проверять, было ли событие отправлено из законного источника.

HTTP-ответы и повторные попытки

По сути, мы должны повторить попытку, если получатель не ответил с кодом ошибки OK HTTP.

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

В заключение

Первоначально опубликовано на yos.io 22 февраля 2017 г.