DEV Community

Cover image for Ming: Um Experimento CQRS em Elixir
Rafael Andrade
Rafael Andrade

Posted on

Ming: Um Experimento CQRS em Elixir

Introdução

Aprender uma linguagem de programação é mais eficaz quando combinado com projetos práticos, já que desafios do mundo real aceleram a maestria. Com experiência em C# e contribuições ativas para o framework Brighter, decidi construir um projeto chamado Ming para aprofundar minhas habilidades em Elixir. Este projeto explora o paradigma de programação funcional do Elixir enquanto implementa padrões como CQRS (Command Query Responsibility Segregation).

Projeto Ming

O Ming se inspira no framework Brighter e no Commanded. Seu foco principal é replicar e adaptar os princípios do CQRS do C# para o Elixir.

Nome

Você pode estar se perguntando por que Ming e se há algum significado. Estava procurando um nome de biblioteca curto, fácil de pronunciar em inglês e próximo de "Brighter". Não encontrei bons nomes em português, eu conheco uma palavra Ming (明) que e bem próximo do que eu queria.

Conceitos Principais

Manipuladores (Handlers)

Handlers no Ming são módulos simples que definem uma função execute/2, responsável por processar comandos/eventos e um contexto de execução. Por exemplo:

defmodule SampleHandler do
  @moduledoc false

  def execute(%Ming.ExampleCommand1{}, %Ming.ExecutionContext{}), do: :ok
end
Enter fullscreen mode Exit fullscreen mode

Isso reflete o design direto das interfaces do C#, mas aproveita o casamento de padrões (pattern matching) do Elixir para maior clareza.

Roteamento de Comandos/Eventos

Para registrar handlers, use use Ming.Router para definir regras de despacho:

defmodule Ming.SampleRouter do
  @moduledoc false
  use Ming.Router

  dispatch [SampleCommand, SampleEvent], to: ReturningAKeyHandler
  dispatch SampleEvent, to: ReturningAKeyHandler
end
Enter fullscreen mode Exit fullscreen mode

O roteador gera pipelines de envio/publicação. Se múltiplos handlers forem registrados para um comando, o Ming retorna {:error, :more_than_one_handler_founded} para garantir um design explícito.

Middleware

Adicione middlewares aos pipelines usando middleware/1, send_middleware/1 ou publish_middleware/1:

defmodule Ming.SampleRouter do
  @moduledoc false
  use Ming.Router

  middleware SomeMiddleware

  dispatch [SampleCommand, SampleEvent], to: ReturningAKeyHandler
  dispatch SampleEvent, to: ReturningAKeyHandler
end
Enter fullscreen mode Exit fullscreen mode

Isso permite lidar com aspectos transversais como logs ou transações, semelhante ao pipeline de middleware do .NET, mas com a pureza funcional do Elixir.

Macros

O Elixir possui macros, uma característica interessante que permite gerar código durante a compilação. Porém, é difícil depurar e entender o que está errado (talvez por falta de experiência). O recurso mais próximo em C# é o gerador de código-fonte, que requer conhecimento da API Roslyn.

Processador de Comandos

No Brighter, IAmACommandProcessor centraliza o envio de comandos e publicação de eventos. O Ming adapta isso com Ming.CommandProcessor:

defmodule SampleCommandProcessor do
  use Ming.CommandProcessor, otp_app: :sample

  router SampleRouter
end
Enter fullscreen mode Exit fullscreen mode

Este módulo registra roteadores e serve como ponto de entrada para interações, aproveitando o OTP do Elixir para robustez.

Rota de Melhorias

  • Documentação: Seguir a estrutura dos guias oficiais do Elixir para melhorar a acessibilidade e publicar via Hex.pm.
  • Funcionalidades: Implementar produção e consumo de mesagens.
  • Testes: Adicionar testes abrangentes para validar tratamento de erros e comportamento de middlewares.

Conclusão

O Ming é um projeto pessoal para CQRS em Elixir, me ajudando a aprender mais sobre o Elixir.

Referência

GitHub do Ming

Top comments (0)