Padrões de Microserviços — CQRS — Command Query Responsability Segregation
Este padrão de projeto diz que você pode ter o seu modelo dados ou domínio exatamente como aprendemos, mas poderiamos ou até devemos ter um modo diferente para consulta dos dados.
Este padrão admite que em um sistema há mais consultas que gravações de dados (10, 15 vezes mais consultas que gravações), e para lidar com isto pode ser necessário termos um modelo otimizado para consultas. Isto quer dizer que, podemos ter um banco de dados para manter os dados de forma integra, e outro otimizado para consulta.
Porém, CQRS não implica em termos banco de dados para leitura e escrita separados, apesar de ser oque mais trás performance para uma aplicação que pode estar sofrendo ao realizar consultas que concorrem com escrita de dados. Isto também significa, que você pode optar por ter bando de dados de leitura e escrita separado sem necessáriamente utilizar CQRS na sua camada de aplicação.
Atenção, CQRS não se limita a bancos de dados, poderíamos ter CQRS implementado utilizando um único banco de dados, atendendo ao conceito na camada de aplicação e não na camada de persistência de dados.
Avaliando oque aprendemos sobre banco de dados relacionais, mais específicamente sobre ACID, CQRS pode nos fazer “quebrar a cabeça”, pois aprendemos que é necessário ter os dados de forma integra e consistente (ACID), mas, CQRS admite que pode haver eventuais inconsistências e está tudo bem.
Elimar Junior: ACID no mundo dos milhões de usuários, não se aplica
CQRS é um padrão que demanda disponibilidade e tolerância, admite-se que pode haver eventual inconsistência dos dados. É claro que isto não é para qualquer sistema, esta necessidade aparece, quando é necessário atender a milhares de requisições.
CAP Theorem
Teorema é uma teoria comprovada — O teorema de CAP Theorem diz que queremos que o sistema seja consistente, disponível e tolerante a particionamento (sharding ou replicação de dados) porém, podemos escolher apenas dois destes três para ter obrigatoriamente, o terceiro será eventual.
Se quero que o sistema seja consistente e disponível, eu não vou ter tolerância a particionamento.
Se quero que o sistema seja consistente e tenha tolerância a particionamento eu não vou ter ele sempre disponível. Vamos entender, ao desejar ter tolerância a particionamento eu quero que os dados seja replicado a todas as bases, logo, mesmo que em um curto período de tempo terei estes dados indisponível.
Arquiteturalmente, podemos dizer que o modelo de filas se encaixa perfeitamente com CQRS. A aplicação aceita a requisição, e a medida que há disponibilidade de recursos executamos as ações necessárias até terminar oque foi solicitado.
Exemplo de uso de filas pode ser encontrado nos comércios eletrônicos, após a confirmação da venda, quando você acompanha o seu pedido, até a entrega. Eventualmente, o seu pedido já pode ter sido entregue, o sistema ainda não mostra este status.
Envio de e-mail, processamentos grandes como geração de pdf (ou outros arquivos), upload e processamento de videos ou imagens são exemplos que podem se adequar no modelo de filas, que, em algum momento pode se adequar também a CQRS e trazer consistência eventual ao invés de consistência obrigatória.
Event sourcing
Diretamente relacionado a CQRS, mas que pode não ser utilizado junto. É necessário quando o a aplicação exige histórico, quando a aplicação exige que seja possível saber como estavam os dados a X dias atrás. É necessário quando precisamos restaurar o estado, a qualquer momento do tempo, executando os eventos passados.
Bancos utilizam deste conceito, pense no extrato, veja como é comum ver o extrato mês a mês. Bancos fazem isto, porque pra ele, é melhor processar uma vez no mês e te mostrar o consolidado, do que processar tudo sempre que for necessário. Para este processamento, ao final do mês, ele recupera todas as movimentações do mês para processar e gerar os valores consolidados, te mostrando apenas o necessário.
Conclusão
Enquanto os seu banco de dados não é gargalo, não é necessário CQRS, este padrão torna-se necessário, apenas quando o banco de dados é o gargalo da escalabilidade da aplicação.
CQRS combina muito bem quando é necessário:
- Integração entre aplicações
- Escalar aplicação para atender a milhares de requisições
Dado que conceitualmente, temos um modelo para persistência e outro para consultas, DTO e GraphQL pode casar muito bem com CQRS.
Contras:
- A complexidade adicionada na aplicação para adotar CQRS é alta
Faça uso de arquitetura emergente e abrace a complexidade no último momento responsável.
Ao querer adotar DDD e Restfull, pode haver um conflito entre os conceitos, pois DDD é focado no domínio, enquanto que Restfull é focado nos dados. Isto se resolve, colocando uma camada de abstração, ou conversão dos objetos trafegados dentro das camadas de sua aplicação, em Java MapStruct pode ajudar neste quesito.
Olha que legal, o Elemar Jr explica muito bem oque é CQRS, recomendo o vídeo abaixo
Revisão do artigo original sobre CQRS feita pelo Alberto, recomendo que assistam…