📌 Eventos de Domínio: O que são e por que usar?
Eventos de domínio registram fatos importantes dentro do sistema. Algo aconteceu – um usuário se cadastrou, uma compra foi feita, um status mudou. Ao capturar isso como um evento, mantemos um histórico claro, facilitando auditorias e análises. Além disso, deixamos o sistema preparado para reagir a mudanças sem bagunçar tudo.
🚀 Implementação na prática
Eventos precisam ser imutáveis. Criou? Não mexe mais. Isso garante integridade e rastreabilidade. Outra coisa: desacoplar ao máximo. Se um evento precisa notificar outra parte do sistema, nada de dependência direta. Deixa ele solto e deixa quem precisar ouvir.
Benefícios?
- Regras de negócio explícitas – Dá pra entender fácil o que está acontecendo.
- Código modular e organizado – Menos acoplamento, mais flexibilidade.
- Consistência entre agregados – Se algo muda, tudo que precisa ser atualizado é notificado automaticamente.
🎯 Quando usar eventos de domínio?
Sempre que precisar notificar outros contextos sem acoplamento. Exemplo clássico:
- Usuário se cadastra → Dispara evento → Outro serviço manda e-mail de boas-vindas.
- Pedido pago → Dispara evento → Estoque e faturamento são atualizados automaticamente.
Bora pro código.
Para fazer isso, vamos evitar expor o dominio a qualquer tipo de infraestrutura de mensagens, com isso evitamos acoplar nossa entidade explicitamente a um recurso externo.
📌 Cenário:
Temos um Usuário que se cadastra no sistema. Quando isso acontece, queremos:
✅ Enviar um e-mail de boas-vindas
Criando o Evento de Domínio
Usamos eventos de domínio para desacoplar esses processos.
Bora pro código! 🎯
export class UsuarioCadastradoEvent {
constructor(public readonly usuarioId: string, public readonly email: string) {}
}
Um evento simples com id e email do novo usuario
Criando o Agregado Raiz
export class Usuario {
private domainEvents: any[] = [];
constructor(public readonly id: string, public readonly nome: string, public readonly email: string) {
this.adicionarEvento(new UsuarioCadastradoEvent(id, email));
}
private adicionarEvento(evento: any) {
this.domainEvents.push(evento);
}
pullEvents(): any[] {
const events = [...this.domainEvents];
this.domainEvents = [];
return events;
}
}
O que rolou aqui?
- Criamos um Usuário.
- Assim que ele nasce, ele já dispara
UsuarioCadastradoEvent
. -
pullEvents()
pega os eventos pendentes e os limpa. ### Criando um Manipulador de Eventos (Event Handler)
import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { UsuarioCadastradoEvent } from '../events/usuario-cadastrado.event';
@EventsHandler(UsuarioCadastradoEvent)
export class EnviarEmailBoasVindasHandler implements IEventHandler<UsuarioCadastradoEvent> {
handle(event: UsuarioCadastradoEvent) {
console.log(`📧 Enviando e-mail de boas-vindas para ${event.email}...`);
}
}
Quando UsuarioCadastradoEvent
acontece, o handler entra em ação. Aqui ele só printa no console, mas poderia enviar e-mail, publicar no Kafka, chamar outro serviço, etc.
Criando o Serviço de Usuário
O NestJS já fornece um Event Bus pronto via @nestjs/cqrs
, então só precisamos usá-lo.
import { Injectable } from '@nestjs/common';
import { EventBus } from '@nestjs/cqrs';
import { Usuario } from '../models/usuario.model';
@Injectable()
export class UsuarioService {
constructor(private readonly eventBus: EventBus) {}
criarUsuario(nome: string, email: string): Usuario {
const usuario = new Usuario(crypto.randomUUID(), nome, email);
usuario.pullEvents().forEach((event) => this.eventBus.publish(event));
return usuario;
}
}
- Criamos o usuário.
- Pegamos os eventos gerados.
- Publicamos no Event Bus do NestJS.
Agora qualquer serviço que ouvir esse evento pode agir sem precisar mudar código aqui.
Lembre-se de registrar no modulo, algo assim:
@Module({
providers: [UsuarioService, EnviarEmailBoasVindasHandler],
})
e claro registrar o cqrs no modulo principal conforme a documentação.
Agora, sempre que um usuário se cadastrar, os eventos certos serão disparados. 🚀
✅ Recapitulando
- Eventos de Domínio organizam melhor as regras de negócio.
- Código desacoplado → Adiciona novos handlers sem mexer no código principal.
- NestJS + CQRS → Event Bus já pronto, sem precisar reinventar a roda.
Top comments (0)