O padrão Fetch Before Process em webhooks

Ao construir sistemas que consomem webhooks, um padrão comum é tratar o webhook recebido como uma notificação e, antes de qualquer processamento, buscar o recurso completo e atualizado na API do provedor. Isso é conhecido como padrão "Fetch Before Process" (buscar antes de processar).

Essa abordagem é uma defesa sólida contra problemas comuns em arquiteturas orientadas a eventos, como receber eventos fora de ordem ou lidar com eventos duplicados. Ao buscar o estado mais recente de um recurso, você garante que o seu sistema sempre trabalhe com os dados mais atuais, o que simplifica a sua lógica e aumenta a confiabilidade.

O que é o padrão 'Fetch Before Process'?

O conceito central do padrão é tratar o evento de webhook recebido como um sinal para disparar um processo, mas, em vez de usar os dados do payload do webhook, você primeiro faz uma chamada de API para buscar o recurso completo e atualizado. Assim você garante que está sempre trabalhando com os dados mais atuais.

Por que 'Fetch Before Process' é um padrão confiável

Sistemas orientados a webhooks são assíncronos por natureza, o que significa que você precisa projetar pensando em desafios como:

  • Ordenação de eventos: você não tem garantia sobre a ordem em que os webhooks chegam. Por exemplo, um evento updated pode chegar antes do evento created do mesmo recurso, causando erros de processamento.
  • Eventos duplicados: a maioria dos provedores de webhooks oferece uma garantia de entrega "at-least-once". Isso significa que você vai receber o mesmo evento mais de uma vez de tempos em tempos, e o seu sistema precisa lidar com isso sem gerar efeitos colaterais indesejados. Esse é o princípio da idempotência.

Buscar o recurso na API logo antes de processá-lo ajuda a resolver esses problemas. Isso permite que você:

  1. Trabalhe com os dados mais atuais: você deixa de depender do retrato dos dados contido no payload do webhook, que pode estar desatualizado.
  2. Valide o estado do recurso: você pode confirmar que o recurso está no estado esperado antes de agir.
  3. Simplifique a idempotência: a sua lógica de processamento passa a se basear no estado real do recurso, e não no evento em si.

Alguns provedores, como a Stripe, estão começando a formalizar esse padrão ao oferecer thin events. São payloads de webhook que contêm apenas o ID do recurso, obrigando o consumidor a buscar os detalhes na API. Para orientações completas sobre como implementar thin events, veja Boas práticas para trabalhar com thin events.

O risco: rate limiting de API em escala

Embora o padrão "Fetch Before Process" seja confiável, ele traz um desafio importante conforme a sua aplicação cresce: os rate limits das APIs.

Imagine um pico repentino de atividade, como uma promoção relâmpago ou uma grande importação de dados, que gera milhares de webhooks em pouco tempo. Se o seu sistema tentar buscar o recurso para cada evento recebido, é fácil gerar um volume alto de requisições por segundo à API. Isso pode ultrapassar os limites do provedor (o da Stripe, por exemplo, costuma ser de 100 requisições de leitura por segundo), fazendo com que ele responda com erros 429 Too Many Requests.

Quando você atinge um rate limit, o seu sistema pode falhar ao processar eventos, gerando inconsistências de dados e uma experiência ruim para o usuário.

Uma abordagem resiliente: desacople a ingestão do processamento

Para obter os benefícios do padrão "Fetch Before Process" sem o risco de atingir rate limits, você pode desacoplar a ingestão de webhooks do processamento usando uma fila.

Veja como funciona essa arquitetura mais resiliente:

  1. Receber e enfileirar: um gateway de eventos (como o Hookdeck) recebe todos os webhooks e os coloca em uma fila.
  2. Controlar a taxa de entrega: você configura o gateway para entregar os eventos à sua aplicação a uma taxa controlada, que se mantém com folga dentro dos limites da API do provedor.
  3. Buscar e processar: o seu código recebe os eventos já com a taxa controlada e pode buscar o recurso na API com segurança antes de processá-lo.

Ao introduzir uma fila, você absorve picos repentinos de volume de webhooks e garante que a sua aplicação processe os eventos em um ritmo estável e administrável. Isso te dá a confiabilidade do padrão "Fetch Before Process" enquanto protege o seu sistema de ser sobrecarregado. Para entender melhor por que o processamento assíncrono é fundamental, veja por que você deveria parar de processar seus webhooks de forma síncrona.