Как их использовать и в чем разница?

Философия программирования Unix заключается в том, чтобы делать (только) одно, но делать это хорошо. Сосредоточиться на одной ключевой задаче сложно, поскольку разработчики видят и чувствуют болевые точки и желания своих пользователей. Чтобы иметь возможность сосредоточиться на основном продукте, но допустить дополнительные функции, о которых мы не можем заботиться, мы разрабатываем системы плагинов. Один из способов сделать это - использовать крючки.
Хук - это способ расширения программного обеспечения.
Подумайте о почтовом клиенте. Почтовый клиент может определить ловушку pre_send, которая получает текущего получателя, строку темы и содержимое электронного письма. Разработчики могут использовать это для расширения программного обеспечения. У вас может быть один плагин, который использует этот хук и добавляет подпись, если она отсутствует. Еще одна ловушка может найти нецензурную лексику и помешать вам отправить это письмо пьяным по ночам, о чем вы пожалеете.
Другой способ расширить программное обеспечение - это событие. Событие просто сообщает плагину, что что-то произошло. Хук может позволить вам остановить дальнейший поток выполнения - например, запретить отправку электронного письма с нецензурной лексикой.
Обратные вызовы
Обратные вызовы - это указатели на функции. Они представляют собой конкретную функцию.
Например, представьте себе поискового робота, который хочет получить содержимое many_urls. Вы можете запускать его последовательно:
for url in many_urls:
get_content(url)
Или вы можете реализовать функцию, которая выполняет все параллельно для каждого аргумента:
parallel_for(get_content, many_urls)
Обратите внимание, что мы не вызываем get_content во втором примере. Мы передаем его как параметр функции. Когда вы передаете функцию в качестве параметра другой функции, вы вызываете ее обратным вызовом.
Обратные вызовы и хуки
Обратные вызовы могут использоваться для реализации ловушек. Если вы еще раз вспомните приведенный выше пример электронной почты, вы можете реализовать его следующим образом:
import email_client email_client.register_pre_send_hook(add_signature) email_client.register_pre_send_hook(detect_swearwords)
Разработчикам email_client необходимо предоставить метод register_pre_send_hook. Они должны сказать вам, что эта функция ожидает функцию в качестве параметра: обратный вызов.
Им нужно сказать вам, что они будут запускать каждый заданный обратный вызов следующим образом:
def send_email():
# Execute all registered hooks
for hook in registered_hooks:
email = hook(email)
Итак, ваш хук получает объект email. Он может изменять этот объект любым способом и перезаписывать содержимое любым способом.
Вебхуки
Веб-перехватчики - это перехватчики, используемые в веб-сервисах. Как и в случае с обычными хуками, вы можете расширить функциональность веб-службы с помощью хуков. Например, Slack позволяет отправлять сообщения по URL-адресу (источнику).

Веб-перехватчики позволяют веб-сайтам передавать вам информацию вместо того, чтобы вы ее извлекали (и опрашивали).
Давайте конкретизируем. Вы наверняка пользуетесь Slack. А может быть, у вас есть система мониторинга типа Sentry. Теперь вы хотите, чтобы сообщение Slack появлялось на определенном канале всякий раз, когда Sentry обнаруживает новую проблему.
Механизм опроса был бы прост - Slack каждые несколько секунд спрашивал Sentry, есть ли новое сообщение. Это потребует от Slack и Sentry гораздо больше ресурсов, чем необходимо. Вместо того, чтобы получать сообщения из Slack, мы хотим, чтобы Sentry отправлял сообщения в Slack.
Веб-серверы обычно не знают своих клиентов. Чтобы иметь возможность передавать информацию в Slack, это необходимо изменить. Клиент (Slack) должен подписаться на сервер (Sentry). Slack необходимо передать URL-адрес Sentry. Код на часовом может выглядеть так:
def subscribe(callback_url):
# callback_url could be
# https://hooks.slack.com/services/T000/B000/XXXXXXXX
store_in_client_list(callback_url)
Обе стороны должны согласовать, какой формат использовать для обмена. В случае со Slack они предоставляют документацию для своей системы веб-перехватчиков. Обе стороны могут это сделать. В конце концов, имеет значение только то, что они согласны.
Когда Sentry обнаруживает новую проблему, они отправляют данные в Slack:
def handle_subscribers(event):
subscribers = event.get_subscribers()
for subscriber in subscribers:
post(subscriber.callback_url, event.data)
Метод post также может использовать возвращаемое значение, но в случае Slack, насколько мне известно, оно просто игнорируется.
Резюме
- Хук - это способ расширения программного обеспечения.
- Обратный вызов - это функция, которая передается в качестве параметра другой функции.
- Вебхук - это приманка в сети. Обычно используется для установления связи между двумя различными системами и, как правило, для перехода от опроса к модели издатель-подписчик.