Voltar ao blog
·2 min de leitura

Arquitetura Event-Driven sem virar um monolito distribuído

Quando eventos ajudam a desacoplar times e quando eles só escondem acoplamento atrás de uma fila. Um guia prático de trade-offs.

arquitetura
backend
sistemas-distribuídos

Arquiteturas orientadas a eventos viraram quase um sinônimo de "sistema moderno". Mas adotar eventos sem entender os trade-offs é a forma mais rápida de transformar um monólito organizado em um monolito distribuído — todas as dependências de antes, agora com latência de rede e debugging por correlação.

O que eventos realmente resolvem

Eventos não são sobre tecnologia (Kafka, SQS, RabbitMQ). São sobre inversão de dependência no tempo. O produtor não sabe — e não precisa saber — quem consome.

Isso desacopla de verdade quando:

  • Times diferentes evoluem produtores e consumidores em ritmos diferentes.
  • O mesmo fato de negócio dispara várias reações independentes.
  • Você precisa absorver picos de carga com um buffer natural.

Quando é acoplamento disfarçado

O sinal de alerta aparece quando o produtor emite um evento e espera uma resposta específica de um consumidor específico para seguir. Isso não é um evento — é uma chamada RPC com passos extras.

Se você precisa saber quem vai consumir e o que vai acontecer depois, você provavelmente quer uma chamada síncrona, não um evento.

Um teste prático

Antes de transformar uma interação em evento, pergunte:

  1. O produtor fica correto mesmo que ninguém consuma o evento?
  2. A ordem de processamento entre consumidores é irrelevante para a correção?
  3. Você consegue conviver com consistência eventual nesse fluxo?

Se a resposta para as três for "sim", eventos provavelmente ajudam. Se alguma for "não", o custo operacional raramente compensa.

Exemplo: notificação vs. cobrança

// ✅ Bom uso de evento: reações independentes a um fato consumado
await orders.markAsPaid(orderId);
await bus.publish("order.paid", { orderId, amount });
// e-mail, fiscal e analytics reagem sem o checkout saber deles

Agora compare com:

// ⚠️ Acoplamento disfarçado: o checkout depende do resultado
await bus.publish("charge.requested", { orderId });
// ...e fica "esperando" um charge.completed para liberar o pedido

No segundo caso, a corretude do checkout depende do consumidor. Uma chamada síncrona ao serviço de pagamento — com um circuit breaker — seria mais simples de operar e de depurar.

Conclusão

Eventos são uma ferramenta de desacoplamento, não um selo de modernidade. Use-os onde a independência entre produtores e consumidores é real. Onde há dependência de resultado, prefira chamadas explícitas. A arquitetura mais fácil de operar quase sempre é a mais honesta sobre suas dependências.