Desmistificando o Brighter: Comandos, Eventos e a Tríade Send-Publish-Post

Introdução No meu artigo anterior sobre o Brighter, demonstrei o uso básico com RabbitMQ. Hoje, vamos explorar as diferenças entre Send, Publish e Post — três métodos centrais para manipulação de mensagens no Brighter. O que é um Barramento (Bus)? Um barramento (ou "data highway") transfere dados entre componentes de um sistema. O Brighter diferencia dois tipos: Barramento Interno(Internal Bus) Opera dentro da aplicação. Otimizado para velocidade (ex: evita serialização de requisições). Registra automaticamente todos os handlers mensagens por padrão. Barramento Externo (External Bubs) Conecta-se fora da aplicação (ex: RabbitMQ, Kafka, AWS SQS/SNS). Requer operações de I/O (rede, acesso a arquivos). Exemplo: Configurando um Barramento Externo com RabbitMQ var rmqConnection = new RmqMessagingGatewayConnection { AmpqUri = new AmqpUriSpecification(new Uri("amqp://guest:guest@localhost:5672")), Exchange = new Exchange("paramore.brighter.exchange"), }; services.AddServiceActivator(opt => {}) .UseExternalBus(new RmqProducerRegistryFactory(rmqConnection, new RmqPublication[] { new() { MakeChannels = OnMissingChannel.Create, Topic = new RoutingKey("greeting.event"), }, } ).Create()); Comandos vs. Eventos O Brighter usa o Padrão de Comando, um padrão de design comportamental que encapsula requisições como objetos. Comando Representa uma ação a ser executada imediatamente. Espera um único handler. Nomes imperativos (ex: CriarUsuario, AtualizarDados). public class CriarUsuario : Command(Guid.NewGuid()) { public string Nome { get; set; } } Evento Representa algo que já ocorreu. Permite múltiplos manipuladores. Nomes no passado (ex: UsuarioCriado, DadosAtualizados). public class UsuarioCriado : Event(Guid.NewGuid()) { public string Nome { get; set; } } Send, Publish & Post: Quando Usar Cada Um Método Caso de Uso Tipo de Barramento Comportamento do Handler Send Comandos Interno Executa um handler Publish Eventos Interno Notifica todos os handlers Post Comandos/Eventos Externo Envia para o barramento externo Exemplos de Uso: // Envia um comando (um handler) commandProcessor.Send(new CriarUsuario { Nome = "Alice" }); // Publica um evento (todos os handler são notificados) commandProcessor.Publish(new UsuarioCriado { Nome = "Bob" }); // Posta para uma fila externa commandProcessor.Post(new PedidoEnviado { PedidoId = 123 }); Exemplo de Código: Send vs. Publish Handler de Comando (Único) public class MeuComandoHandler : RequestHandler { private readonly ILogger _logger; public MeuComandoHandler(ILogger logger) => _logger = logger; public override MeuComando Handle(MeuComando comando) { _logger.LogInformation( "Comando recebido: ID={Id}, Texto={Texto}", comando.Id, comando.Texto ); return base.Handle(comando); } } Handlers de Evento (Múltiplos) public class MeuEventHandler1 : RequestHandler { private readonly ILogger _logger; public MeuEventHandler1(ILogger logger) => _logger = logger; public override MeuEvento Handle(MeuEvento evento) { _logger.LogInformation( "Handler 1: Evento ID={Id}, Texto={Texto}", evento.Id, evento.Texto ); return base.Handle(evento); } } public class MeuEventHandler2 : RequestHandler { // Lógica similar ao MeuEventHandler1 } Execução: var processor = provider.GetRequiredService(); // Envia um comando (um manipulador) processor.Send(new MeuComando { Texto = "Olá, Comando" }); // Publica um evento (ambos os manipuladores são acionados) processor.Publish(new MeuEvento { Texto = "Olá, Evento" }); Pontos-Chave Usar Send com um comando que tenha múltiplos handlers gera exceção. Post ignora manipuladores locais e delega ao barramento externo. Conclusão O Padrão de Comando do Brighter desacopla ações de sua execução, ideal para sistemas escaláveis. Em artigos futuros, exploraremos retries, pipelines e monitoramento. Código Completo: Repositório GitHub Referências: Documentação do Brighter Guia do Padrão de Comando Padrão de Comando (Wikipedia)

Mar 22, 2025 - 13:36
 0
Desmistificando o Brighter: Comandos, Eventos e a Tríade Send-Publish-Post

Introdução

No meu artigo anterior sobre o Brighter, demonstrei o uso básico com RabbitMQ. Hoje, vamos explorar as diferenças entre Send, Publish e Post — três métodos centrais para manipulação de mensagens no Brighter.

O que é um Barramento (Bus)?

Um barramento (ou "data highway") transfere dados entre componentes de um sistema. O Brighter diferencia dois tipos:

Barramento Interno(Internal Bus)

  • Opera dentro da aplicação.
  • Otimizado para velocidade (ex: evita serialização de requisições).
  • Registra automaticamente todos os handlers mensagens por padrão.

Barramento Externo (External Bubs)

  • Conecta-se fora da aplicação (ex: RabbitMQ, Kafka, AWS SQS/SNS).
  • Requer operações de I/O (rede, acesso a arquivos).

Exemplo: Configurando um Barramento Externo com RabbitMQ

var rmqConnection = new RmqMessagingGatewayConnection
{
  AmpqUri = new AmqpUriSpecification(new Uri("amqp://guest:guest@localhost:5672")),
  Exchange = new Exchange("paramore.brighter.exchange"),
};

services.AddServiceActivator(opt => {})
  .UseExternalBus(new RmqProducerRegistryFactory(rmqConnection,
     new RmqPublication[]
     {
        new()
        {
          MakeChannels = OnMissingChannel.Create,
          Topic = new RoutingKey("greeting.event"),
        },
      }
  ).Create());

Comandos vs. Eventos

O Brighter usa o Padrão de Comando, um padrão de design comportamental que encapsula requisições como objetos.

Comando

  • Representa uma ação a ser executada imediatamente.
  • Espera um único handler.
  • Nomes imperativos (ex: CriarUsuario, AtualizarDados).
public class CriarUsuario : Command(Guid.NewGuid())
{
   public string Nome { get; set; }
}

Evento

  • Representa algo que já ocorreu.
  • Permite múltiplos manipuladores.
  • Nomes no passado (ex: UsuarioCriado, DadosAtualizados).
public class UsuarioCriado : Event(Guid.NewGuid())
{
   public string Nome { get; set; }
}

Send, Publish & Post: Quando Usar Cada Um

Método Caso de Uso Tipo de Barramento Comportamento do Handler
Send Comandos Interno Executa um handler
Publish Eventos Interno Notifica todos os handlers
Post Comandos/Eventos Externo Envia para o barramento externo

Exemplos de Uso:

// Envia um comando (um handler)  
commandProcessor.Send(new CriarUsuario { Nome = "Alice" });  

// Publica um evento (todos os handler são notificados)  
commandProcessor.Publish(new UsuarioCriado { Nome = "Bob" });  

// Posta para uma fila externa  
commandProcessor.Post(new PedidoEnviado { PedidoId = 123 });  

Exemplo de Código: Send vs. Publish

Handler de Comando (Único)

public class MeuComandoHandler : RequestHandler<MeuComando>  
{  
    private readonly ILogger<MeuComandoHandler> _logger;  

    public MeuComandoHandler(ILogger<MeuComandoHandler> logger) => _logger = logger;  

    public override MeuComando Handle(MeuComando comando)  
    {  
        _logger.LogInformation(  
            "Comando recebido: ID={Id}, Texto={Texto}",  
            comando.Id, comando.Texto  
        );  
        return base.Handle(comando);  
    }  
}  

Handlers de Evento (Múltiplos)

public class MeuEventHandler1 : RequestHandler<MeuEvento>  
{  
    private readonly ILogger<MeuEventHandler1> _logger;  

    public MeuEventHandler1(ILogger<MeuEventHandler1> logger) => _logger = logger;  

    public override MeuEvento Handle(MeuEvento evento)  
    {  
        _logger.LogInformation(  
            "Handler 1: Evento ID={Id}, Texto={Texto}",  
            evento.Id, evento.Texto  
        );  
        return base.Handle(evento);  
    }  
}  

public class MeuEventHandler2 : RequestHandler<MeuEvento>  
{  
    // Lógica similar ao MeuEventHandler1  
}  

Execução:

var processor = provider.GetRequiredService<IAmACommandProcessor>();  

// Envia um comando (um manipulador)  
processor.Send(new MeuComando { Texto = "Olá, Comando" });  

// Publica um evento (ambos os manipuladores são acionados)  
processor.Publish(new MeuEvento { Texto = "Olá, Evento" });  

Pontos-Chave

  • Usar Send com um comando que tenha múltiplos handlers gera exceção.
  • Post ignora manipuladores locais e delega ao barramento externo.

Conclusão

O Padrão de Comando do Brighter desacopla ações de sua execução, ideal para sistemas escaláveis. Em artigos futuros, exploraremos retries, pipelines e monitoramento.

Código Completo:

Repositório GitHub

Referências: