Imagine que o petshop da Maya, do Pancho e do Romeu cresceu. Agora tem centenas de agendamentos por dia, relatórios complexos sendo gerados o tempo todo, e o sistema começa a travar. O problema? Leitura e escrita brigando pelos mesmos recursos. O CQRS resolve exatamente isso.
O que é CQRS?
Command Query Responsibility Segregation — ou simplesmente CQRS — é um padrão arquitetural que separa as operações de escrita das operações de leitura em modelos distintos.
O nome vem de um princípio mais antigo chamado CQS (Command Query Separation), criado por Bertrand Meyer, que diz:
"Um método deve ou fazer algo (comando) ou responder algo (consulta) — nunca os dois ao mesmo tempo."
O CQRS leva essa ideia para o nível arquitetural: modelos, bancos e fluxos completamente separados para cada responsabilidade.
O problema que o CQRS resolve
Na maioria dos sistemas tradicionais, leitura e escrita usam o mesmo modelo, o mesmo banco e as mesmas classes. Funciona bem no começo, mas com o crescimento surgem conflitos:
- Leituras tendem a ser frequentes, complexas e precisam de respostas rápidas
- Escritas tendem a ser menos frequentes, mas exigem consistência e validação rigorosa
- Otimizar para um prejudica o outro — índices que aceleram leitura podem travar escrita, e vice-versa
É como usar a mesma porta para entrada e saída de um estádio cheio. Funciona até o jogo acabar.
Como o CQRS funciona
A separação acontece em dois lados:
┌─────────────────────────────────┐ │ Aplicação │ └──────────┬──────────────┬────────┘ │ │ ┌──────────▼──┐ ┌────▼──────────┐ │ Commands │ │ Queries │ │ (Escrita) │ │ (Leitura) │ └──────────┬──┘ └────┬──────────┘ │ │ ┌──────────▼──┐ ┌────▼──────────┐ │ Banco de │ │ Banco de │ │ Escrita │ │ Leitura │ │ (Otimizado │ │ (Otimizado │ │ p/ gravar) │ │ p/ consultar)│ └─────────────┘ └───────────────┘
Commands — o lado da escrita
Um Command representa uma intenção de mudança no sistema. Ele carrega os dados necessários para executar uma ação e não retorna dados — só confirma se a operação foi bem-sucedida ou não.
No petshop: AgendarConsulta, CancelarAgendamento, CadastrarAnimal são Commands. Eles mudam o estado do sistema e seguem todas as regras de negócio e validações.
Queries — o lado da leitura
Uma Query representa uma solicitação de dados. Ela não muda nada no sistema — só busca e retorna informações, geralmente otimizadas para a tela ou relatório que vai exibi-las.
No petshop: BuscarAgendamentosDoDia, ListarAnimaisPorDono, GerarRelatorioMensal são Queries. Elas podem usar views, caches, bancos desnaturalizados — qualquer coisa que torne a leitura mais rápida.
CQRS com Event Sourcing
O CQRS é frequentemente combinado com Event Sourcing — um padrão onde, em vez de salvar o estado atual, você salva todos os eventos que aconteceram.
No petshop: em vez de guardar que a consulta da Maya está com status "cancelada", você guarda a sequência de eventos:
ConsultaAgendadaConsultaConfirmadaConsultaCancelada
O estado atual é sempre reconstruído a partir desses eventos. Isso traz um histórico completo e auditável de tudo que aconteceu no sistema — algo valioso em domínios como financeiro, saúde e jurídico.
Vantagens
Escalabilidade independente: o lado de leitura recebe muito mais tráfego? Escale só ele. Sem impacto na escrita.
Modelos otimizados para cada lado: o banco de escrita pode ser normalizado e consistente. O banco de leitura pode ser desnormalizado, com dados pré-agregados para responder rápido.
Código mais claro: Commands e Queries têm responsabilidades explícitas. Você nunca mistura lógica de negócio com lógica de apresentação no mesmo lugar.
Histórico e auditoria: combinado com Event Sourcing, você tem um log imutável de tudo que aconteceu no sistema.
Desafios
Consistência eventual: como os bancos de leitura e escrita são separados, pode haver um pequeno atraso entre gravar e o dado aparecer nas consultas. Para a maioria dos casos isso é aceitável — mas nem sempre.
Complexidade maior: dois modelos, dois bancos, sincronização entre eles. Para sistemas simples, é over-engineering claro.
Curva de aprendizado: a equipe precisa entender bem o padrão para não criar uma bagunça com responsabilidades misturadas mesmo tendo a separação estrutural.
Quando usar CQRS?
✅ Use quando:
- Leitura e escrita têm volumes muito diferentes
- As consultas são complexas e lentas por causa do modelo de escrita
- O domínio é rico em regras de negócio e se beneficia de Commands explícitos
- Você precisa de auditoria completa (combinado com Event Sourcing)
❌ Evite quando:
- O sistema é um CRUD simples
- O time ainda está aprendendo arquitetura
- A consistência eventual é inaceitável para o negócio
CQRS na série
Se você acompanhou os posts anteriores, vai perceber onde o CQRS se encaixa:
- Os Commands carregam e protegem as Entities e Aggregates do DDD
- As Queries vivem na camada de Interface Adapters da Clean Architecture
- Em sistemas com Microsserviços, cada serviço pode ter seu próprio modelo CQRS
- Os Domain Services do DDD orquestram os Commands
Não é um padrão isolado — é uma peça que se conecta naturalmente com tudo que vimos até aqui.