CQRS, o que ele resolve mesmo?

preview_player
Показать описание
No episódio de hoje discutimos sobre CQRS. O debate é feito sobre o texto escrito por Greg Young dez anos atrás, quando ele trouxe o termo CQRS e trouxe a visão dele sobre o problema arquitetural que tínhamos naquele momento e como o CQRS poderia ajudar na sua arquitetura.

Lembrando que um texto de dez anos atrás está longe de ser velho. Muito pelo contrário, o termo CQRS está super na moda e aplicações são implementadas seguindo a sugestão de Greg Young.

A pergunta que que fica: será que CQRS é realmente uma proposta de solução para algo?

# Saiba mais sobre mim :).

# Links úteis
Рекомендации по теме
Комментарии
Автор

Tenho acompanhado bastante seu trabalho, muito bacana. Parabéns.
Tenho apenas um caso de uso para CQRS, que é justamente blindar o core da aplicação contra excesso de leituras.
Já trabalhei com uma sistema que recebia média de 60mm/dia... Em determinados momentos, os recursos computacionais do banco de dados concorriam entre read / write... E prejudicava a performance como um todo. Nesse caso, uma view não resolveria.
Se pudesse voltar no tempo, tentaria aplicar cqrs jogando a leitura para uma outra instância de BD.
Abraço

omarcury
Автор

Acredito que cada nicho tem suas necessidades e o artigo do Greg suporta a necessidade desse público. Muitos precisam de uma receita de bolo e não querem saber o porquê dos ingredientes.

peneluc
Автор

Bacana o vídeo, é sempre bom gerar discussões sobre determinados assuntos que estão na moda, pois muita gente iniciante começa a utilizar como se não houvesse amanhã em projetos pequenos que um MVC básico que qualquer framework entrega hoje em dia resolve.
Comecei a estudar sobre DDD em 2014, a partir da leitura do livro do Vaughn Vernon sobre o livro original. Gostei bastante do conteúdo, muito do que é descrito vem como tudo em formato de padrões, e padrão são apenas um catálogo de um conjunto de soluções genéricos para ações tomadas por muitas outras pessoas e que alguém resolveu catalogar, logo se você já estuda e trabalha a um tempo muitas coisas você já consegue entender, saber quando usar, quando não usar e assim vai.
Muitos devs acham que é só pegar o catálogo de padrões e sair adicionando ao código como se fosse uma bala de prata, que Brooks lá atrás já reforça que isso não existe.
Mas sabemos como são os iniciantes :), todos nós já fomos!

Nunca implementei CQRS puro, da forma que ele descreve, mas para alguns projetos vejo muita vantagem da abordagem Commands+Handlers para definir o fluxo de alteração de estado da aplicação.
Expressar a linguagem ubíqua no código, da forma que eu entendo é você ter classes que efetuam operações que expressam a mesma linguagem entre equipe técnica e de negócio, logo se você entende de OO e conversa com a equipe de domínio para bom entendimento, você meio que já vai seguir essa linguagem, criando métodos de "ação" nos seus objetos que fazem referencia à linguagem de domínio, e não criar objetos com uma porrada de getter e setter sem sentido.
Vejo a vantagem de ao invés você ter isso espalhado por services e objetos, você ter no início do seu código fonte, todos os comandos que sua aplicação pode fazer:
src/Comando/CriarPedido

Basicamente isso é um catálogo do que seu sistema é capaz de executar, e quais são os dados necessários para tal, e outra vantagem, que de novo não é para qualquer sistema, é você poder serializar essa mensagem e gravar para um processamento posterior.
Com isso vejo uma grande facilidade de manutenção, pois delimita a forma que o fluxo da informação vai ser tratada no sistema. Todo mundo vai saber que o pedido no sistema é criado sempre da mesma maneira, dentro do handler que trata o comando CriarPedido e não ficar com regras espalhadas por vários lugares. Você pode resolver isso com um service também essa parte em si, mas não tem as outras vantagens acima.
Entre a execução e a alteração do estado final, alguns modelos de negócios requerem diversos tipos de integração, e diversas regras de negócio que dependem muitas vezes de elementos externos ao contexto daquela execução, ou seja, não é o caso de projetos pequenos.
No handler você ao final da execução e alteração de estado pode lançar os famosos eventos, que façam sentido para a equipe de negócio, afim de poder tanto gerar auditoria se for necessário, quanto facilitar a estruturação para limpeza de cache, envios de webhooks e processamento de execuções lentas em filas, tudo isso pode ser feito de outras maneiras, mas enxergo essa forma ser mais elegante e padronizada de fazer operações que quase todos os sistemas hoje em dia que não sejam crud ou pequenos precisam.
Enfim já comecei a me estender muito e até fugi um pouca ahaha. Não quero mudar a opinião de ninguém, quero apenas trazer um pouco mais de como acredito que a abordagem de Comando+Handler+Linguagem Ubíqua+Eventos de Domínio ajudam no desenvolvimento de sistemas enterprise.

andrekiffer
Автор

Estou atualmente estudando esse padrão junto com Event Source, e o que pude notar até o momento, é que esse modelo serve pra casos extremos de escalabilidade, o que não é realidade pra 99% das empresas. Quem sei que usou ou usa é o Twitter. No caso do Twitter, a escrita e a leitura concorriam no mesmo banco, que se não me engano era mysql. Aí implementaram esse padrão pra resolver escalabilidade, separando operações de gravação num banco e num outro cacheado (Redis) desnormalização no formato de dados prontos pra serem lidos pelo cliente sem transformação no js, porém ele traz problemas como consistência eventual, que dependendo do negócio pode ser crítico. No caso do Twitter um twite demorar mais ou menos pra ser atualizado não faz tanta diferença assim, mas numa empresa financeira pode fazer muita (vi na prática devs empurrarem essa ideia numa fintech e aí qdo questionei o porque da utilização não tinham resposta). Pra fechar acho que esse tipo de padrão tem q ser muito avaliado, principalmente os trade-offs, pois pouquíssimas empresas tem a necessidade de escalabilidade do Twitter, Google, etc.

denisschimidtdeoliveira
Автор

Oi Alberto!
Primeiramente.. parabéns pela a análise achei genial os pontos que levantastes e concordo com 99%.
Trabalho em um empresa que adota CQRS e, no meu humilde entendimento, o pattern gera mais burocracia que valor. Sobretudo porque mistura duas coisas boas para sistemas grandes: separação de escrita e leitura +event driven.
Acredito que o event driven é uma boa abordagem para sistemas grandes (replay, interceptors, etc.)...
Já a divisão de de fluxo de escrita e leitura... para sistemas pequenos não faz muito sentido.. mas para sistemas grandes, faz sentido, sobretudo porque separa modelagens como:
1) controle de authorização e acesso (que pode ser muito diferente para escrita e leitura)
2) transação (lidar com dados de leitura quando se pensa transação pode ser um problema)
3) validação
4) applicações específicas (e.g.: sistemas com data lake, e IA, onde a modeficação de um crud pode influenciar outros sistemas complexos)
Contudo.. separação de leitura e escrita não precisa de CQRS.. pode ser feito com SOA tradicional.. da mesma forma que event driven pode ser feito sem separação de leitura e escrita.
Então.. o que tenho vivido com CQRS é que... CQRS = event driven + read/write segregation... só que de forma confusa e inchada.

Mas o (pequeno) ponto que.. em que concordo com a visão do autor (não com o argumento)... é que as aplicações web clássicas são baseadas em SOA, em geral com serviços stateless. E stateless é programação funcional... não é orientação a objetos. E nesse sentido, fica realmente difícil de programar DDD, pois um domain parte da prerrogativa do estado como POSSÍVEL incluenciador do comportamento do objeto (observa o grifo no possível).
Então.. acho que o autor usou como argumento de "venda" uma dor real: web é baseado em SOA state less, DDD é stateful e é necessário pensar um pouco para encaixar os dois; e ofereceu equivocadamente uma solução com: event driven + read/write segragation (que são coisas muito antigas), como uma coisa nova.

economiadigitalbrasil
Автор

Bem interessante num ambiente com muita concorrência de dados (leitura x escrita), mas daí a dar um nome pra isso e chamar de uma 'nova' arquitetura é coisa de quem quer vender livros e cursos. Basicamente é: se o volume de acesso ao banco for muito grande, deixe um banco para escrita e outro para leitura.

pgnt
Автор

Mas quando vc utiliza uma view pra resgatar os dados, aí vc praticamente migrou pro CQRS não é?! Esses dias eu tive que modelar algo parecido, só que não usei view, e sim uma fila que inseria os dados em outro local, e então os usuários consultavam desse outro local?

Isso não seria um CQRS?

TheEmanuelvictor
Автор

Oi alberto, qual vídeo você explica como analisar as responsabilidades ?, não encontrei.

MeMateus
Автор

Cqrs eh lindo pra Inglês ver… esses dias comecei um curso e desisti no meio, um CRUD com 50+ classes, um monte de pastas pra na maioria 1 arquivo dentro…
Horrível de dar um start na aplicação….

Na boa, o Velho e simples eh melhor na minha humilde opinião

albertoneto
Автор

Interessante a reflexão. Mas esse tipo de arquitetura serve mais para sistemas grandes e que recebem pancadas de requisições ao mesmo tempo, ou em horários de pico. A maioria dos devs vão ficar no velho CRUD, pois eh a demanda do mercado.

tav
Автор

3 anos depois, sua visão sobre CQRS mudou?

likesofc
Автор

Não penso que vou fazer você mudar de ideia.
Após ter testado uma APP com CQRS com um colega a impressão que ficou foi "Ótimo agora para inserir um usuário preciso passar por 25 passos"


Em muitos casos ele só gera complexidade desnecessária e que acabam sendo usados por desenvolvedores entediados que querem fazer algo novo. (E lideres tem que entender que isso também é um problema que eles precisam lidar)


Só vejo que faz sentido se você já faz uso de event sourcing (e faz porque precisa) e basicamente já faz com que as entradas do seu sistema se tornem eventos que você guarda em algum lugar.
E isso se aplica apenas em casos onde você tem um domínio complexo, que será dividido por um time grande e você precisa conseguir escalar escritas e leituras separadamente.


Entendo que assim isso deve ser aplicado apenas aonde realmente necessário dentro de um contexto delimitado, fazer vários serviços com CQRS ou fazer com que o domínio todo seja assim é apenas complicar sem motivo.
É ganhar ônus sem bônus.


Então assim como micro-serviços ajudam a escalar múltiplas equipes divino partes do problema, CQRS pode ser uma divisão ainda maior de uma dessas partes do problema.
De novo, tudo isso é ACHO, até porque nunca fiz nada assim e no passado quando cogitamos preferimos não complicar sem precisar, isso nunca impediu de fazer event sourcing aonde foi necessário sem nunca ter feito CQRS.

O que acha?





Abraço

pedrommrabello
Автор

Na minha opinião acredito que a separação que o autor faz exemplificando a arquitetura web tradicional está relacionada a diferença entre System of Events e System of State quando tratamos Event Sourcing como escolha para construção do sistema. No caso de uma arquitetura padrão, o DB armazena o estado atual do objeto somente o que acontece de forma diferente quando tratando aggregates.

llgertel
Автор

A única vantagem de CQRS que posso enxergar é poder usar um banco de dados de escrita e outro de leitura, uma (ou várias) réplica apenas para essa finalidade. Mas isso se resolve com dois datasources e desacoplamento da conexão com o banco com os métodos de manipulação dos dados.

rodrigo
Автор

Gostei da sua visão, mas ela é real para aplicações corporativas, com centenas de usuários. Mas com milhões de usuários, não é possível aplicar um DDD perfeito. É necessário desnormalizar, é necessário ter redundância, é necessário separar serviços.

davaug