Command Query Responsibility Segregation (CQRS) é uma abordagem para desenvolvimento de software onde desenvolvemos estruturas de dados distintas para gravação (comandos) e para a leitura (consultas). CQRS não prescreve, explicitamente, a adoção de eventos. Entretanto, é comum utilizar, com CQRS, algum padrão de notificação por eventos ou até event sourcing.
Greg Young, responsável pelas formalizações de CQRS e Event Sourcing, costuma indicar a adoção conjunta das duas técnicas.
Geralmente, a implementação das consultas (query-side) costuma ser mais simples. Afinal, validações e outras complexidades do domínio costumam ficar restritas às operações que causam modificações persistentes de estado (command-side).
O “afrouxamento” da implementação das consultas permite a redução da quantidade de dados trafegando na rede.
Temos encontrado, com frequência, implementações REST-like que fazem trafegar na rede estruturas complexas de dados que são utilizadas apenas parcialmente. A justificativa é continuar utilizando os mesmos modelos definidos no domínio. Resultado? Telas de consulta que relacionam nomes e telefones de clientes mas que são abastecidas por JSONs gigantescos que oneram a rede e os custos de serialização e desserialização.
CQRS ajuda na definição de abstrações eficientes.
Outra característica recorrente de implementações de CQRS são interfaces com o usuário que evidenciam operações de negócio (domínio) no lugar de simples manipulações de dados. Em termos simples, o padrão CQRS não costuma ser utilizado com implementações tradicionais de CRUD.
É possível conceber um sistema com comandos como CreateEmployee, UpdateEmployee, etc. Entretanto, consideramos que a complexidade adicionada pelo padrão, nesses casos, acaba não se justificando.
Um bom modelo com CQRS deveria permitir a definição de comandos como RegisterEmployee, UpdateEmployeeAddress, RegisterEmployeePromotion, etc. Sendo que, comandos assim, obviamente implicariam em um design de interação mais rico do que aqueles que temos visto frequentemente (muito mais ajustado, inclusive, para utilização em dispositivos móveis) e modelados a partir de uma compreensão mais rigorosa do domínio (consideramos difícil desassociar CQRS de DDD).
Implementações de CQRS com comandos com “mais significado” facilitam o “enfileiramento” de mensagens empregando alguma técnica de mensageira.
Embora não seja um imperativo, é comum que implementações CQRS utilizem fontes de dados distintas. Nesses casos, é comum utilizar notificação por eventos (que carregam dados relacionados) para orquestrar a consistência entre as bases.
Greg Young destaca que uma base de dados persistindo eventos poderia ser utilizada para a implementação dos comandos e uma base de dados “consolidada” poderia ser utilizada na implementação das consultas.
Mesmo que não sejam utilizadas bases de dados distintas, é importante destacar que caching costuma fazer mais sentido para a implementação das consultas (query-side) do que das gravações (command-side). Nesses casos, notificações por eventos são boas alternativas para implementações de estratégias para invalidação do cache.
Já implementou software usando CQRS? Como foi sua experiência?
Olá. Estou estudando CQRS e gostei muito de sua aula no youtube. Estou com dúvidas sobre eventos e notificações, como enviar um email apos uma operação