Trabalhando com eventos

Em sistemas modernos, orientados a boas práticas de arquitetura como DDD (Domain-Driven Design) e Clean Architecture, eventos são mecanismos fundamentais para modelar mudanças de estado e comunicação assíncrona entre componentes ou sistemas. Um evento representa algo que já aconteceu no domínio da aplicação e que pode interessar a outras partes do sistema ou a serviços externos.

Eventos de Domínio

Eventos de domínio representam fatos importantes que ocorreram dentro do contexto da aplicação. Eles são gerados e consumidos internamente no sistema, permitindo a propagação de mudanças de estado de forma desacoplada, ou seja, sem que os objetos precisem conhecer diretamente uns aos outros.

Quando utilizar um Evento de Domínio?

  • Sempre que uma operação gerar uma mudança significativa no domínio e houver necessidade de notificar ou acionar outras partes do sistema.
  • Para manter o modelo de domínio coeso, possibilitando que processos diferentes sejam disparados sem criar dependências diretas entre módulos ou serviços.

No Lino, criar um novo evento de domínio é simples. Você pode executar:

lino event new

O assistente do CLI solicitará:

  • Serviço – Serviço no qual o evento será criado.
  • Módulo – Módulo em que o evento será criado (apenas em serviços modulares).
  • Entidade – Entidade em que o evento será criado / associado.
  • Tipo de evento – Evento de domínio ou evento de integração.
  • Nome do evento – Nome utilizado no domínio, associado a entidade.

Exemplo

Criando o evento de domínio UserCreated associado a entidade User, o sistema cria automaticamente um evento com o nome UserCreatedDomainEvent. Esse nome deixa claro para qualquer parte do sistema que consuma o evento que a ação de criação de usuário já foi concluída.

Estrutura gerada pelo Lino:

MyApp/
└── src/
    └── Services/
        └── MyService/
            └── Domain/
                ├── MyApp.MyService.Domain.csproj
                └── Aggregates/
                    └── Users/
                        ├── User.cs
                        ├── Errors/
                        ├── Events/
                        │   └── UserCreatedDomainEvent.cs
                        ├── Repositories/
                        └── Resources/

Manipuladores de Eventos de Domínio

Um Domain Event Handler é uma classe responsável por reagir a um Evento de Domínio, executando ações relacionadas ao estado interno da aplicação, sempre dentro do mesmo contexto transacional.

O objetivo principal desses manipuladores é manter o sistema coeso e desacoplado, permitindo que regras adicionais sejam aplicadas sem sobrecarregar a lógica central da entidade ou do agregado.

Por exemplo, após a criação de um User, pode ser necessário atualizar estatísticas, gerar um log interno ou notificar outro agregado. Essas ações fazem sentido dentro do domínio e podem ocorrer de forma síncrona, garantindo consistência imediata.

No entanto, operações que dependem de recursos externos — como envio de e-mails ou chamadas a APIs de terceiros — não devem ser executadas diretamente a partir de eventos de domínio, pois isso prenderia a transação a tarefas lentas ou instáveis. Nestes casos, o domínio pode gerar um evento de integração (registrado em Outbox), que será processado posteriormente de maneira assíncrona e resiliente.

Características principais:

  • Reage a um evento, mas nunca o modifica.
  • Executa apenas operações in-process e relacionadas à consistência do domínio.
  • Garante que tudo rode dentro da mesma transação.

Para criar um novo manipulador de eventos de domínio, basta executar o comando:

lino event-handler new

O assistente do CLI solicitará:

  • Serviço – Serviço no qual o manipulador de evento será criado.
  • Módulo – Módulo em que o manipulador de evento será criado (apenas em serviços modulares).
  • Entidade – Entidade em que o manipulador de evento será criado.
  • Tipo de evento – Evento de domínio ou evento de integração.
  • Evento - Evento que será consumido.
  • Nome do manipulador de evento – Nome utilizado que será associada a entidade e evento de domínio.

Exemplo

Criando o manipulador de evento de domínio UserCreated associado a entidade User e evento UserCreatedDomainEvento sistema cria automaticamente um manipulador de evento com o nome UserCreatedDomainEventHandler.

Estrutura gerada pelo Lino:

MyApp/
└── src/
    └── Services/
        └── MyService/
            └── Application/
                ├── MyApp.MyService.Application.csproj
                └── UseCases/
                    └── Users/
                        ├── Commands/
                        ├── EventHandlers/
                        │   └── Domain/
                        │       └── UserCreatedDomainEventHandler.cs
                        ├── Logging/
                        ├── Queries/
                        └── Resources/

Eventos de Integração

Eventos de Integração são mensagens que informam que algo importante aconteceu e precisam ser compartilhadas com sistemas externos ou outros microserviços.

Diferente dos eventos de domínio, aqui o objetivo é comunicação entre sistemas e sincronização de estados.

Quando criar um Evento de Integração:

  • Quando uma mudança no seu sistema precisa ser refletida em outro sistema.
  • Quando seu microserviço precisa publicar mudanças para que outros microserviços reajam.

Diferenças principais entre Domain Events e Integration Events:

Aspecto Evento de Domínio Evento de Integração
Público-alvo Interno Externo
Acoplamento Baixo (interno) Necessário (entre sistemas)
Tempo de processamento Imediato Pode ser assíncrono, com garantias de entrega
Persistência necessária Não obrigatória Sim (para confiabilidade e resiliência)

No Lino, criar um novo evento de integração é simples. Você pode executar:

lino event new

O assistente do CLI solicitará:

  • Serviço – Serviço no qual o evento será criado.
  • Módulo – Módulo em que o evento será criado (apenas em serviços modulares).
  • Entidade – Entidade em que o evento será criado / associado.
  • Tipo de evento – Evento de domínio ou evento de integração.
  • Nome do evento – Nome utilizado nos eventos de integração, associado a entidade.

Exemplo

Criando o evento de integração UserCreated associado a entidade User, o sistema cria automaticamente um evento com o nome UserCreatedIntegrationEvent. Esse nome deixa claro para qualquer parte do sistema que consuma o evento que a ação de criação de usuário já foi concluída.

Estrutura gerada pelo Lino:

MyApp/
└── src/
    └── Services/
        └── MyService/
            └── IntegrationEvents/
                ├── MyApp.MyService.IntegrationEvents.csproj
                └── Users/
                    └── UserCreatedIntegrationEvent.cs

Manipuladores de Eventos de Integração

Um Integration Event Handler é uma classe responsável por consumir um Evento de Integração, normalmente publicado por outro serviço ou contexto, e então executar ações específicas no seu próprio domínio.

Esses handlers recebem eventos por meio de mecanismos de mensageria (como RabbitMQ, Kafka, Azure Service Bus etc.), geralmente em conjunto com o padrão Outbox, que garante entrega confiável e processamento assíncrono.

Por exemplo, quando um evento UserCreated é publicado por um serviço de Identidade, o respectivo handler em outro contexto pode reagir enviando um e-mail de boas-vindas ou chamando APIs externas. Essas operações podem ser mais lentas ou sujeitas a falhas, mas como são tratadas fora da transação principal, não comprometem a consistência interna da aplicação.

Características principais:

  • Reage a eventos que representam fatos de negócio relevantes para outros contextos.
  • Executa operações que podem ser lentas ou externas (ex.: envio de e-mails, chamadas a APIs).
  • É processado de forma assíncrona e resiliente, muitas vezes com retentativas e monitoramento.
  • Garante que falhas externas não afetem a transação original do domínio.
  • Facilita a integração entre bounded contexts e sistemas distribuídos.

Para criar um novo manipulador de eventos de integração, basta executar o comando:

lino event-handler

O assistente do CLI solicitará:

  • Serviço – Serviço no qual o manipulador de evento será criado.
  • Módulo – Módulo em que o manipulador de evento será criado (apenas em serviços modulares).
  • Entidade – Entidade em que o manipulador de evento será criado.
  • Tipo de evento – Evento de domínio ou evento de integração.
  • Serviço – Serviço em que o evento a ser consumido existe.
  • Módulo – Módulo em que o evento a ser consumido existe (apenas em serviços modulares).
  • Entidade – Entidade em que o evento a ser consumido existe.
  • Evento - Evento que será consumido.
  • Nome do manipulador de evento – Nome utilizado que será associada a entidade e evento de integração.

Exemplo

Criando o manipulador de evento de integração SendEmailOnUserCreated associado a entidade User e evento UserCreatedIntegrationEvento sistema cria automaticamente um manipulador de evento com o nome SendEmailOnUserCreatedIntegrationEventHandler.

Estrutura gerada pelo Lino:

MyApp/
└── src/
    └── Services/
        └── MyService/
            └── Application/
                ├── MyApp.MyService.Application.csproj
                └── UseCases/
                    └── Users/
                        ├── Commands/
                        ├── EventHandlers/
                        │   └── Integration/
                        │       └── SendEmailOnUserCreatedIntegrationEventHandler.cs
                        ├── Logging/
                        ├── Queries/
                        └── Resources/
Ocorreu um erro não tratado. Recarregar 🗙