Sharing is caring!

Quando pensamos em startups ou em empresas de tecnologia já consolidadas, como facebook e Apple, costumamos ter em mente que o principal motivador destas companhias é a inovação como um fim. Contudo, o maior desafio de uma empresa de tecnologia consiste em utilizar a tecnologia como um facilitador ou um meio para satisfazer uma necessidade e encantar um cliente.

Na MovilePay, fintech do grupo Movile, o desafio não é diferente. Trabalhamos todo o nosso acervo tecnológico com o objetivo de prover a melhor experiência aos nossos clientes e parceiros. Para tal, é essencial estar sempre antenado sobre inovações, ferramentas e paradigmas tecnológicos que surgem no mercado.

Um dos nossos objetivos de negócio é construir uma carteira digital para o público B2C. Quando lidamos com pagamentos surgem algumas exigências de performance, imutabilidade e auditoria que não encontramos em outros tipos de aplicação e uma arquitetura orientada a eventos favorece, de forma natural, essas premissas.

Ao iniciar o desenvolvimento de uma aplicação, é bastante comum pensarmos primeiramente na modelagem de dados: quais entidades compõem o sistema, quais as propriedades das entidades e quais seus relacionamentos. Depois, adaptamos nossa aplicação para funcionar com esse modelo, surgindo assim as famosas classes de serviço com enorme quantidade de linhas.

Nesse artigo vamos mudar nosso modo de pensar para priorizarmos as ações realizadas pela nossa aplicação. Para entendermos um pouco mais desse mundo vou dar uma breve introdução do que são CQRS (Command Query Responsibility Segregation) e Event Sourcing e como esses modelos podem ser aplicados para a implementação de uma aplicação totalmente orientada a eventos.

 

CQRS

A essência do CQRS, que significa Segregação por Responsabilidade de Consulta e Comando, é utilizar modelos diferentes para atualizar e ler informações.

A maioria dos sistemas hoje em dia são tratados como CRUDs, ou seja, utilizamos um único modelo para realizar operações de escrita, edição, leitura e, quando não precisamos mais deles, a exclusão. Geralmente tentamos manter o modelo retornado o mais fiel possível ao usado pelo armazenamento.

Conforme o tempo passa as necessidades do sistema vão ficando mais complexas e começamos a nos afastar desse modelo. Não é muito difícil surgir um cenário em que precisamos retornar dados agrupados ou no caso de uma atualização receber dados que são usados apenas para validações. Isso faz com que várias representações da mesma informação sejam criadas, deixando o modelo cada vez mais carregado e complexo.

CRSS01

O CQRS propõe separarmos a aplicação em modelos diferentes para escrita e leitura, que seguindo o padrão CQRS são os Comandos e Consultas. Essa separação significa utilizar objetos diferentes, em processos separados, e às vezes até mesmo em hardware separado.

O exemplo que vamos abordar nessa Story é um cadastro de contas bancárias. No momento que o usuário solicita uma mudança isso é roteado para o modelo de comando que realizará as alterações necessárias e informará o modelo de consulta para que as novas informações sejam exibidas para o usuário.

CRSS02.PNG

Isso pode ser feito de várias formas. Os modelos na memória podem compartilhar um mesmo banco de dados ou podem ter bases separadas, mas para isso precisaríamos de um método diferente para manter a comunicação entre os dois modelos. E esse problema dá o gancho para o nosso próximo tópico.

Event Sourcing

Na minha opinião, uma das melhores definições de Event Sourcing é a descrita por Martin Fowler em um artigo no seu blog pessoal.

Nós podemos buscar o estado de uma aplicação para encontrar o estado atual do mundo, e isso responde muitas perguntas. Entretanto há momentos que nós não só queremos ver onde nós estamos, mas também queremos saber como chegamos lá.
Martin Fowler

Ela apresenta de forma clara, um dos maiores benefícios desse modelo.

CRSS03.PNG

Quando trabalhamos com um modelo tradicional conseguimos consultar em nosso banco de dados somente o último estado de um objeto e em muitos casos isso basta. Porém, em alguns momentos somente o estado atual não é suficiente, precisamos saber também como foi o caminho que percorremos até esse resultado.

O Event Sourcing garante que todas as alterações em uma aplicação sejam armazenadas em uma sequência de eventos. Assim podemos montar projeções do estado atual da nossa aplicação bem como consultar os eventos. Isto permite montar projeções do passado e gerar insumos  para auditorias.

Trazendo para o nosso exemplo, imagine que uma conta bancária seja criada, depois editada várias vezes e por fim fechada. Se estivermos olhando somente para o estado final da conta conseguimos verificar que a mesma está com o status CLOSED e um saldo de R$ 15,00. Porém, isso não nos dá informação suficiente, tampouco diz porque a conta foi fechada.

CRSS04.PNG

Quando trabalhamos com Event Sourcing fazemos um pouco diferente. Ao invés de uma tabela com o dado consolidado teríamos um stream de eventos dessa conta. Não se apegue sobre como estamos armazenando esses eventos. Hoje existem várias soluções bem melhores para lidar com eventos. Utilizamos o mesmo estilo de base do exemplo anterior para facilitar o entendimento.

CRSS05

Poderíamos processar esses dados como um stream de eventos e montar diversas visões diferentes, como por exemplo, uma base consolidada no Elasticsearch para melhorar a performance de consulta da nossa aplicação, ou uma base filtrada para alguma necessidade específica.

O que mais importa é que nesse modelo conseguimos saber que a conta foi fechada por inatividade e tratar possíveis inconsistências nas bases consolidadas, caso houvessem, apenas olhando para os eventos, além de ter uma auditoria natural do nosso negócio.

Conclusões

Há muitas vantagens em ter uma arquitetura orientada a eventos, mas antes de decidir utilizá-la, você deve verificar se o custo-benefício faz  sentido para o seu cenário. Uma arquitetura desse tipo pode aumentar um pouco a complexidade, tanto de implementação quanto de manutenção.

Na MovilePay temos reuniões semanais do time de engenharia (guilda de backend) para discutir assuntos como este. Depois fazemos PoCs e implementamos essas mudanças de forma gradual em sistemas menores. Após validar os resultados e ter certeza que será algo que vai favorecer nosso negócio, propagamos para aplicações maiores.

Espero ter conseguido apresentar alguns benefícios desse tipo de aplicação e também fazer com que reflitam na hora de escolher qual será a arquitetura da sua próxima aplicação!

Referências

https://martinfowler.com/bliki/CQRS.html

https://microservices.io/patterns/data/cqrs.html

https://martinfowler.com/eaaDev/EventSourcing.html