Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Arquitetura orientada a eventos no Node.js

Atualizado em: 15 de outubro de 2026

Terminal Linux usado em desenvolvimento e administração de aplicações Node.js

Event-Driven Architecture no Node.js organiza sistemas ao redor de eventos que representam mudanças relevantes. Em vez de um serviço chamar diretamente todos os próximos passos, ele publica um fato e consumidores independentes reagem.

Essa abordagem aumenta desacoplamento e escalabilidade, mas introduz consistência eventual, duplicação de mensagens, ordenação e observabilidade distribuída. O objetivo não é tornar tudo assíncrono, e sim escolher eventos quando autonomia e resiliência justificam a complexidade.

Evento, comando e mensagem

Um comando solicita uma ação: CriarPedido. Um evento informa um fato: PedidoCriado. Mensagem é o envelope transportado por Kafka, RabbitMQ, SQS ou outro broker.

{
  "id": "evt-123",
  "type": "orders.order-created.v1",
  "occurredAt": "2026-10-15T12:00:00Z",
  "correlationId": "req-91",
  "data": {
    "orderId": "o-7",
    "customerId": "c-2",
    "totalCents": 15990
  }
}

Produtores e consumidores

O produtor publica um contrato e não deve conhecer todos os consumidores. Cada consumidor processa o evento conforme sua responsabilidade.

  • Estoque reserva itens;
  • Faturamento cria cobrança;
  • Analytics atualiza métricas;
  • Notificações envia confirmação.

Pub/Sub e filas

Em uma fila, uma mensagem costuma ser processada por um consumidor do grupo. Em pub/sub, vários consumidores independentes recebem o mesmo evento. Brokers oferecem combinações diferentes desses modelos.

Consistência eventual

Depois de criar um pedido, estoque e analytics podem levar alguns segundos para refletir a mudança. A interface deve comunicar estados intermediários como “processando” em vez de prometer consistência imediata.

Entrega pelo menos uma vez

A maioria dos sistemas práticos trabalha com entrega pelo menos uma vez. Isso significa que consumidores devem aceitar duplicatas.

async function consumir(event) {
  await db.transaction(async trx => {
    const novo = await inbox.registrar(event.id, trx);
    if (!novo) return;
    await projeção.aplicar(event, trx);
  });
}

Outbox

Persistir o estado e publicar diretamente no broker cria uma janela de falha. O padrão Outbox grava o evento na mesma transação do negócio e um worker publica depois.

Consulte Domain Events no Node.js.

Ordenação

Ordenação global reduz throughput. Preserve ordem por chave quando necessário, como orderId. Inclua versão do aggregate para detectar eventos fora de ordem.

Particionamento

Uma chave de partição deve distribuir carga sem quebrar ordem necessária. IDs muito concentrados podem criar hot partitions.

Contratos

Eventos públicos precisam de schema, documentação e compatibilidade. JSON Schema, Avro ou Protobuf podem validar payloads.

  • adicione campos opcionais de forma compatível;
  • não renomeie significado silenciosamente;
  • versione eventos incompatíveis;
  • mantenha exemplos e testes de contrato.

Veja JSON Schema no Node.js.

Retries

Falhas transitórias devem usar backoff e jitter. Erros permanentes não devem bloquear a partição indefinidamente.

const delay = Math.min(30000, 500 * 2 ** attempt) * (0.5 + Math.random());

Dead Letter Queue

Após tentativas limitadas, mova a mensagem para uma DLQ com motivo, stack segura e metadados. Crie processo de análise e reprocessamento.

Backpressure

Consumidores devem controlar concorrência conforme banco, CPU e APIs externas. Mais workers não ajudam se a dependência já está saturada.

Schema Registry

Um registry centraliza versões e regras de compatibilidade. Mesmo sem ferramenta dedicada, mantenha schemas versionados no repositório e valide no CI.

Observabilidade

Monitore:

  • taxa de publicação e consumo;
  • lag por consumidor;
  • idade da mensagem mais antiga;
  • retries e DLQ;
  • latência ponta a ponta;
  • eventos duplicados;
  • erros por tipo.

Propague traceId, correlationId e causationId.

Segurança

Use autenticação no broker, TLS, ACL por tópico ou fila e payload mínimo. Eventos podem permanecer armazenados por muito tempo; evite dados sensíveis desnecessários.

Testes

Teste serialização, schema, idempotência, mensagens fora de ordem, retry, DLQ e reprocessamento. Use um broker real em testes de integração críticos.

Quando usar

Eventos são úteis quando múltiplos consumidores reagem ao mesmo fato, integrações precisam ser resilientes ou workloads devem ser absorvidos de forma assíncrona.

Quando evitar

Uma chamada síncrona simples pode ser melhor quando o usuário precisa de resposta imediata, a operação é pequena e não há necessidade de desacoplamento.

Erros comuns

  • publicar sem Outbox;
  • consumidor não idempotente;
  • evento usado como RPC;
  • payload sem versão;
  • retry infinito;
  • sem DLQ operacional;
  • particionamento inadequado;
  • não medir lag;
  • misturar dados sensíveis no evento.

Conclusão

Event-Driven Architecture no Node.js permite construir serviços autônomos e absorver picos com mensageria. O benefício depende de contratos estáveis, idempotência, consistência eventual bem comunicada e operação madura.

Comece com um fluxo onde o desacoplamento traga valor claro. Adote Outbox, retries limitados, DLQ e métricas desde o início.

Consulte o material de Martin Fowler sobre sistemas orientados a eventos e a documentação de eventos do Node.js.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita