Command Query Responsibility Segregation: separar o modelo que altera dados (commands) do modelo que os lê (queries). O termo foi popularizado por Greg Young a partir do princípio CQS de Bertrand Meyer: um método ou muda o estado, ou devolve um resultado, nunca os dois.
Por que separar
Escrita e leitura têm necessidades diferentes:
- A escrita precisa de regras, validação e consistência: um modelo normalizado e rico.
- A leitura precisa ser rápida e já vir no formato da tela: dados desnormalizados, às vezes em outro banco (Elasticsearch, Redis, uma view materializada).
Com modelos separados, cada lado escala e evolui por conta própria. Em muitos sistemas há muito mais leituras que escritas.
O preço
- Consistência eventual: depois de um command, a leitura pode demorar um instante para refletir a mudança. A interface precisa lidar com isso.
- Mais peças: dois modelos, eventos e projeções para manter.
Não precisa ser tudo ou nada: dá para começar com o mesmo banco e apenas classes separadas para escrita e leitura, e só separar o armazenamento quando a carga pedir.
CQRS combina bem com event sourcing (guardar os eventos em vez do estado atual), mas um não exige o outro.
Veja também: System design e Arquitetura hexagonal.
- Para se aprofundar: CQRS, de Martin Fowler