DEV Community

Cover image for CQRS (Command Query Responsibility Segregation)

CQRS (Command Query Responsibility Segregation)

Definições Relacionadas

  • CQRS: Segregação de Responsabilidade entre Comandos e Consultas.
  • CQS: Separação de Comandos e Consultas. Princípio de design de software que afirma que cada método deve ser ou um comando que realiza uma ação ou uma consulta que retorna dados, mas não ambos.
  • Command (comando): Instrução que acciona uma mudança no estado do sistema. Ex: registar, actualizar e excluir.
  • Query (consulta): Solicitação de obtenção de dados no sistema. Ex: obter por id, listar todos, pesquisar.
  • Segregation (Separação): Divisão de responsabilidades de leitura e escrita, garantindo que uma operação apenas uma função.
  • Event Driven (Orientado a evento): Paradigma de programação onde as modificações no sistema são comunicados atrvés de eventos. No caso do CQRS é usado para sincronizar dados entre a leitura e escrita.
  • Operação de Leitura: Acção que envolve recuperação de dados no sistema.
  • Operação de Escrita: Acção que envolve modificações no sistema.

Conceito

O CQRS é um padrão arquitectural que separa as responsabilidades de leitura e escrita de dados em um sistema. Essa separação visa optimizar o desempenho, a escalabilidade e a flexibilidade da aplicação, além de promover a consistência e a segurança dos dados.

Origem

CQRS foi popularizado por Greg Young, um dos pioneiros em padrões arquitecturais para sistemas complexos. Greg Young introduziu o CQRS como uma evolução do padrão CQS de Bertrand Meyer.
Greg Young expandiu esse princípio para a arquitectura de sistemas, separando completamente os modelos de leitura e escrita em diferentes componentes, o que facilita o design de sistemas altamente escaláveis e performáticos.
A introdução do CQRS coincidiu com a crescente popularidade de arquitecturas baseadas em eventos e sistemas distribuídos, onde a necessidade de escalabilidade e consistência eventual se tornou cada vez mais evidente.

Componentes Básicos

  • Interface do Cliente: Inicia as requisições ao sistema. A interface pode ser um Navegador, uma Aplicação Desktop ou CLI.
  • Controllers: Tratam do roteamento da aplicação, separando os comandos das consultas.
    • Command Controller: Lida com as operações que alteram o estado da aplicação.
    • Query Controller: Lida com consultas, ou seja, operações que não alteram o estado do sistema. - Commands / Requests: Estruturas de dados que serão manipuladas nos Handlers, de Comando e Consulta.
  • Handlers: Responsáveis pelo processamento das comandos e consultas.
    • Command Handler: Processa comandos, aplicando regras de negócio e actualizando na base de dados.
    • Query Handler: Processa consultas, recuperando dados da base de dados
  • Base de Dados: Local de persistência dos dados, podendo ser:
    • Base de dados Única: Usado tanto para operações de leitura quanto de escrita.
    • Base de dados de Escrita: Para operações de escrita. Usado para armazenar e actualizar dados.
    • Base de dados de Leitura: Para operações de leitura. Os dados são sincronizados a partir da base de dados de escrita.

Fluxo de Operações

Comandos (Commands)

  1. O cliente envia um comando via Command Controller.
  2. O Command Controller delega o processamento do comando ao Command Handler.
  3. Command Handler aplica as regras de negócio e atualiza a base de dados de escrita. Após a operação, a base de dados de leitura pode ser sincronizada com a de escrita para refletir as mudanças.

Consultas (Queries)

  1. O cliente envia uma consulta via Query Controller.
  2. O Query Controller delega o processamento da consulta ao Query Handler.
  3. O Query Handler recupera os dados da base de dados de leitura (ou da base de dados única, se aplicável) e retorna os resultados para o cliente.

Quando adoptar CQRS?

O CQRS é ideal para sistemas que apresentam:

  • Alto volume de leitura: E-commerce, Sistemas de recomendação de produtos, Sistemas de busca
  • Operações de escritas complexas: Sistemas bancários, Aplicações de trading, Sistemas de gestão de estoque.
  • Assimetria nas cargas de leitura e escrita: Sistemas de gerenciamento de projectos, Sistemas de gerenciamento de tarefas.
  • Requisitos de segurança rigorosos: Sistemas de pagamento, Sistemas de autenticação e autorização
  • Complexidade nas operações de escrita: Sistemas de gerenciamento de conteúdo, Sistemas de gerenciamento de workflows.
  • Necessidade de escalar de forma independente: Sistemas de rede social, Sistemas de streaming de vídeo.
  • Modelo de dados Complexo: Sistemas de gerenciamento de dados científicos, Sistemas de gerenciamento de dados de saúde.
  • Necessidade e uso de eventos: Sistemas de integração de aplicativos, Sistemas de notificação em tempo real.

Benefícios

  • Orientado a funcionalidades: Permite que Desenvolvedores diferentes se concentrem em funcionalidades específicas do sistema, facilitando a adição de funcionalidades.
  • Escalabilidade: Melhora a capacidade de escalar diferentes partes do sistema, de forma independente.
  • Flexibilidade: Permite adoptar diferentes estratégias para leitura e escrita.
  • Desempenho: Melhora o desempenho devido a optimização de leitura e escrita separadamente.
  • Segurança: Facilita a implementação de políticas de segurança distintas para operações de leitura e escrita.

Desafios

  • Complexidade: Introduz complexidade no design do sistema, dificuldade ma aprendizagem, depuração e testes.
  • Consistência: Garantir consistência entre leitura e escrita pode ser desafiador. A base de dados de leitura requer sincronização com a base de dados de escrita para evitar inconsistências.
  • Replicação: Necessidade de replicar dados entre diferentes modelos pode ser complexa.
  • Overengeneering para projectos pequenos: Pode ser um exagermos para projectos com requisitos simples.
  • Maturidade da equipa: A equipa de desenvolvimento precisa ter experiência e habilidades em CQRS e tecnologias relacionadas para garantir uma implementação bem-sucedida.
  • Tempo de Implementação: A implementação é demorada devido a complexidade. O fluxo de uma operação, pode estar representada em varios arquivos.
  • Verbosidade do código: Resulta em um código verboso e detalhado, em relação a outros padrões de arquitectura.

Recomendações

O padrão CQRS possui muitos benefícios e desafios. Portanto, devemos levar em considerações os seguintes pontos:

  • Adopção em pequenas partes do projecto: Implementar CQRS gradualmente, começando com partes específicas do sistema que se beneficiem mais dessa arquitectura.
  • Evolução Gradual: Iniciar com uma abordagem simples e evoluir a arquitectura conforme as necessidades do projecto se tornam mais complexas.
  • Revisão contínua da arquitectura: Monitorar e revisar constantemente a arquitectura para garantir que ela continua a atender às necessidades do sistema e ajustar conforme necessário.
  • Capacitação da equipa: Garantir que a equipa de desenvolvimento tenha o conhecimento e a formação necessários para implementar e manter a arquitectura CQRS.
  • Monitoramento e logging: Configurar monitoramento e logging para detectar e solucionar problemas rapidamente.
  • Testes automatizados: Implementar testes automatizados e para assegurar a qualidade e consistência do sistema, especialmente na comunicação entre as partes de comando e consulta.
  • Documentação detalhada: Manter uma documentação abrangente para facilitar a compreensão e manutenção do sistema.

Conclusão

O CQRS é um padrão arquitectural poderoso que pode agregar valor e trazer grandes benefícios em termos de escalabilidade, desempenho e segurança, especialmente em sistemas complexos com requisistos rigorosos. No entando deve ser avaliado cuidadosamente para evitar overengeneering em projectos simples ou pequenos.

Exemplo

Implementação de uma API REST adoptando CQRS com .NET e SQL Server.
Repositório:

Image description

Image description

Image description

Image description

Image description

Image description

Image description

Image description

Image description

Image description

Image description

Top comments (0)