Nesse artigo irei explicar um pouco sobre Webhooks, seu uso e um exemplo prático ao final, espero que ajude seus estudos!
Inicio!
O conceito formal fornecido pela RedHat é:
"Um webhook é uma função de retorno de chamada baseada em HTTP que viabiliza a comunicação lightweight e orientada por eventos entre duas interfaces de programação de aplicações (APIs, na sigla em inglês)."
Para sintetizar, um webhook existe para comunicar que um evento aconteceu em um sistema A para um sistema B.
Se pararmos para pensar, esse conceito de "comunicar um evento que aconteceu em um sistema A para um sistema B" é muito útil, já que muitos sistemas precisam desse tipo de funcionalidade recorrentemente.
Um exemplo legal e bem comum é um e-commerce, que depende de muitos sistemas diferentes se comunicando para funcionar adequadamente como sistema de pagamento, entrega, o marketplace, mecanismos de recomendações, etc.
Para ficar mais fácil o exemplo que eu vou dar não irei mencionar muitas variáveis como essas no sistema, então, imagine então um sistema de e-commerce simples com apenas um serviço de pagamento.
O e-commerce é naturalmente responsável por promover a venda e captar todas as informações necessárias do cliente, validar os dados, etc.
Já o serviço de pagamento tem como objetivo de efetivamente comprovar o pagamento a respeito do pedido do cliente.
É intuitivo pensar que você só poderá atualizar a página de feedback do pedido para "pagamento efetuado" depois que realmente o pagamento for efetuado, mas como a gente vai fazer para que o e-commerce saiba que o cliente efetivamente pagou o pedido?
O serviço de pagamento é um sistema diferente do e-commerce, como a gente vai fazer para poder integrar ambos?
A primeira abordagem.
A primeira e mais obvia solução é vc fazer uma função dentro do seu e-commerce que vai ficar fazendo requisições para o serviço de pagamento, perguntando se o cliente fez o pagamento daquele pedido, você não vai querer ficar disparando toda hora essa requisição e pode fazer com que ela faça a requisição de 1 em 1 minuto, parece OK certo?
ERRADO!
Vamos supor que ocorreu o primeiro pedido do e-commerce e agora só falta o cliente realizar o pagamento, agora é só esperar ele pagar e dentro de 1 minuto sua aplicação vai atualizar a tela.
No entanto... o usuário não paga depois desse 1 minuto e nem da o ar da graça nas próximas 2hrs, o que aconteceu foi que ele, enquanto fazia o pedido no e-commerce, esqueceu que tinha que levar a vó dele para o treino de Jiu Jitsu e como ele é um bom neto, vai ficar para prestigiar o treino de sua vó e vai demorar 2hrs para voltar. Mas o mesmo usuário pensou "vou deixar o pedido aqui, quando voltar eu pago".
Nessas duas horas que se passaram seu e-commerce fez 120 requisições para o seu serviço se pagamento sem qualquer informação relevante do pagamento, sem qualquer nova atualização, perdendo capacidade computacional e gerando desperdício no sistema (Leia perca de dinheiro).
E isso foi apenas de um usuário imagina se fosse 100 usuários, que é um numero baixo, seria 12000 requisições jogadas completamente no lixo.
E qual seria uma abordagem melhor?
Abordagem com Webhook
Agora imagina que a gente pode ter um intermediário que avisa para o e-commerce que o pagamento de um pedido foi realizado? Isso seria ótimo certo? Iriamos fazer com que todo aquele desperdício da primeira abordagem fosse excluído e o sistema teria as informações atualizadas mais breve possível.
E esse intermediário ótimo tem nome, ele se chama Webhook. Com o Webhook sendo orientado a evento, podemos avisar por meio dos serviço de pagamento que um determinado pedido foi pago para o e-commerce, de forma simples e fácil, a lógica é a seguinte:
O serviço de pagamento avisa que foi pago um determinado pedido para o webhook, o webhook repassa essa informação para o e-commerce que atualiza agora a tela do usuário para "pagamento realizado" ou outra mensagem escolhida.
Fazendo o primeiro webhook simples!
Vamos colocar a mão na massa e ver como realmente como implementar webhooks. Como eu já expliquei anteriormente webhooks servem para comunicar que um evento aconteceu em um sistema A para um Sistema B, para deixar mais enxuto, vou fazer APIs simples para do webhook.
Para isso é necessário os seguintes elementos:
- Primeira API: A primeira API fica esperando um evento acontecer na segunda, ligando com o exemplo que eu dei, poderia ser a API do e-commerce.
- O webhook
- Segunda API: Que acontece o evento e informa para o webhook para a primeira API, ligando com o exemplo, seria o serviço de pagamento.
As APIs nesse caso poderiam também ser um serviço ou outro sistema!
Só para deixar claro, os exemplos a seguir foram feitos em Ruby com o micro-framework Sinatra, pelo fato de ser a linguagem que eu estou mais gostando de estudar e aprender, mas você pode implementar o mesmo exemplo na sua ferramenta preferida.
Também deixei todo os códigos em um repositório no Github para que você não precise ficar copiando, clicka aqui.
Vamos começar criando a segunda API que é responsavel por notificar o evento para o webhook, o que ela precisa fazer é justamente fazer uma requisição simples para o webhook, como a gente faria para uma API normalmente. Segue o código.
require 'sinatra'
require 'rest-client'
get '/' do
puts 'test second app'
end
post '/service' do
# Logica do serviço de pagamento...
data_service = {
'body' => 'dados para o primeiro serviço'
}
RestClient.post(
'http://127.0.0.1:4568/webhook/event-created',
data_service.to_json,
{content_type: :json, accept: :json}
)
end
Agora vamos criar o próprio webhook, para isso você precisa criar outra API normalmente, no entanto, essa API vai receber os dados que vem da API 2 (no exemplo que dei, serviço de pagamento) e vai passar para a API 1 por meio de uma requisição POST (no exemplo que dei, e-commerce). Não atoa Webhook são chamados também como APIs inversas.
Ou seja, o webhook recebe uma requisição de uma API (ou serviço) e faz outra requisição POST passando esses dados para outra API (ou serviço).
require 'sinatra'
require 'rest-client'
post '/webhook/event-created' do
puts 'chegou no webhook'
request_first_app = RestClient.post(
'http://127.0.0.1:4567/recieve_event',
request.body,
headers: { 'Content-Type': 'application/json' }
)
end
Só ficou faltando criar a primeira API, que vai receber os dados da Segunda API por meio do webhook, fazendo assim com que tudo funcione da forma adequada.
require 'sinatra'
before do
request.body.rewind
@request_payload = JSON.parse request.body.read
end
get '/' do
puts 'hello world'
end
post '/recieve_event' do
puts "evento que ocorreu no sistema 2, os dados são: #{@request_payload['body']}"
# logica após receber o dado do body....
end
Agora o que vai acontecer? Quando você fizer uma requisição POST na rota /service
da segunda API essa ela mesma vai executar sua logica e avisar para o webhook que determinado evento evento ocorreu passando os dados escolhidos, o webhook repassa para a primeira API.
Antes de testar, se atente em rodar as APIs e o Webhook nas portas certas, caso contrario, pode ser que tenha dor de cabeça com isso, logo as portas nesse meu exemplo são as seguintes:
- first_app: porta 4567
- weebhook: porta 4568
- second_app: porta 4569
Após rodar todas as aplicações com:
ruby src/nome_do_servico -p numero_da_porta
Faça uma requisição POST com body JSON para o endpoint http://127.0.0.1:4569/service, você notará que o dado mockado que você mandou no second_app
vai ser logado da mesma forma no first_app
, o que prova que conseguimos implementar de forma bem-sucedida o webhook.
É isso!
Espero que esse artigo tenha te ajudado a entender sobre webhooks! Qualquer coisa estou a disposição de ajudar e trocar uma ideia sobre tech nas minhas redes sociais, é isso!
Top comments (0)