Application patterns

Application patterns

Este é o segundo artigo da série sobre Microservice Architecture Pattern Language. Tratarei aqui sobre a primeira camada de padrões na ordem de importância para desenhar um solução de arquitetura de micros serviços.

Application patterns se referem aos padrões de desenho de aplicativos que se concentram na estruturação e organização da lógica de negócios e interface do usuário de uma aplicação usando a arquitetura de micros serviços.

Eles se concentram em como a lógica de negócios e a interface do usuário são implementadas e gerenciadas, independentemente do número de serviços.

Uma vez que tenha decidido pelo uso da arquitetura de micro serviços precisa decompor o negócio em serviços. O padrão que vai ajudar com esta tarefa é Decomposition.

Decomposition é um padrão de arquitetura de micros serviços que consiste em dividir uma aplicação em pequenos serviços independentes.

Cada serviço é responsável por uma única funcionalidade ou conjunto de funcionalidades, e esses serviços são desacoplados uns dos outros, o que permite que eles sejam desenvolvidos, testados e escalados de forma independente.

Decomposition é uma parte importante de Application patterns pois permite que a aplicação seja dividida em pequenos serviços que podem ser desenvolvidos, testados e escalados de forma independente.

Isso facilita a manutenção e melhoria da aplicação, pois cada serviço pode ser atualizado ou corrigido sem afetar o funcionamento de outros serviços. Além disso, o desacoplamento dos serviços também permite que eles sejam implementados em diferentes linguagens e tecnologias, o que dá flexibilidade ao desenvolvimento.

A decomposição é geralmente realizada com base nas funcionalidades do negócio da aplicação, e os serviços são projetados para serem altamente coesos e altamente acoplados. Isso permite que os serviços sejam escalados de forma independente e que possam ser substituídos ou atualizados sem afetar o funcionamento do sistema.

São quatro padrões para decomposição em micro serviços:

  1. Decompose by business capability é uma técnica de decomposição que se baseia nas funcionalidades de negócio da aplicação.
  2. Decompose by subdomain é uma técnica de decomposição que se baseia em dividir a aplicação em subdomínios específicos. Cada subdomínio representa uma área específica de negócios ou de conhecimento e cada serviço é projetado para lidar com as necessidades específicas desse subdomínio.
  3. Self-contained service é uma abordagem para o desenvolvimento de micro serviços que se concentra em garantir que cada serviço seja altamente coeso e altamente acoplado. Isso é alcançado tornando cada serviço auto-suficiente, ou seja, cada serviço contém todos os recursos necessários para funcionar de forma independente, sem depender de outros serviços.
  4. Service per team é uma abordagem para o desenvolvimento de micro serviços que se concentra em atribuir cada serviço a uma equipe de desenvolvimento específica. Isso significa que cada equipe é responsável por desenvolver, testar e gerenciar um ou mais serviços.

Em resumo, Decompose by subdomain se concentra em dividir a aplicação em áreas de conhecimento, enquanto Decompose by business capability se concentra em dividir a aplicação em funções de negócios. Ambas as abordagens visam garantir que os serviços sejam altamente coesos e altamente acoplados, permitindo escalabilidade e flexibilidade.

O Domain-Driven Design (DDD) é uma abordagem de desenvolvimento de software que se concentra em modelar o domínio de negócios de uma aplicação. A combinação de DDD e o padrão Decomposition pode ajudar a projetar soluções de micro serviços que sejam robustas e escaláveis, pois permite que os serviços sejam projetados de acordo com os subdomínios específicos e que possam ser escalados independentemente uns dos outros.

Aplicação dividida em serviços cria-se um novo problema.  Como garantir a qualidade, escalabilidade e flexibilidade dos dados em uma solução de micro serviços?

Os Data patterns são padrões de arquitetura de dados que ajudam a garantir a qualidade, escalabilidade e flexibilidade dos dados em uma solução de micro serviços.

Esses padrões são projetados para lidar com desafios comuns relacionados aos dados, como garantir a consistência dos dados, gerenciar a escalabilidade dos dados e garantir a segurança dos dados.

No alt text provided for this image

Eles são divididos em dois grupos, Database architecture e Maintaining data consistency.

Database architecture A arquitetura de banco de dados é um aspecto crítico de qualquer solução de micro serviços, pois é responsável por garantir a qualidade, escalabilidade e segurança dos dados.

A arquitetura de banco de dados deve ser projetada para atender aos requisitos de desempenho, escalabilidade e segurança da solução de micro serviços.

É aqui que vai decidir se usará um banco de dados compartilhado (Shared database) entre os serviços ou um banco de dados por serviço (Database per service).

No alt text provided for this image


Decidindo pelo padrão Database per service nasce outros problemas.

Como consultar informações que estejam distribuídas em várias bases de dados?

Como manter a consistência dos dados entre os serviços em uma transação?

O padrão API Composition e CQRS ajudam com os problemas de consulta.

Em geral, Querying via API Gateway é uma opção mais simples e escalável para lidar com consultas em arquitetura de micro serviços, enquanto CQRS é uma opção mais avançada e escalável, mas também mais complexa.

Já o padrão Saga ajuda com o problema de transações distribuídas.

No alt text provided for this image

Maintaining data consistency é o processo de garantir que os dados armazenados em diferentes partes do sistema estejam consistentes entre si.

Isso é especialmente importante em arquiteturas de micro serviços, onde os dados podem ser armazenados em diferentes serviços ou bancos de dados.

Uma das principais formas de manter a consistência de dados é usando transações distribuídas, que permitem que as operações em vários bancos de dados sejam realizadas como se fossem uma única operação.

Isso garante que, se uma operação falhar, as outras também falharão e os dados não ficarão inconsistentes.

Outra forma de manter a consistência de dados é usando técnicas de replicação de dados, como a replicação síncrona ou assíncrona.

Isso permite que os dados sejam replicados entre diferentes bancos de dados, garantindo que as informações estejam sempre atualizadas e consistentes.

Além disso, é importante considerar as regras de negócios do sistema e designar validações e integridade de dados para garantir a consistência de dados.

Para sistemas de grande porte, é importante usar ferramentas de monitoramento e alertas para detectar e corrigir eventuais inconsistências de dados.

Vou deixar os detalhes do Padrão Saga para um artigo só dele. Vamos continuar com os dois últimos grupos de padrões da camada Application patterns, Testing e UI.

No alt text provided for this image

Após decompor seu negócio em serviços, resolver os problemas de consulta e transação precisa ter como testar se está tudo funcionando. Testar os serviços individuais não garante que uma transação que tenha a participação de vários serviços funcione.

Para ajudar com os problemas de testes temos três padrões:

  • Service Integration Contract Test: Este é um tipo de teste que é usado para garantir que os serviços em uma arquitetura de micro serviços estejam se comunicando corretamente e atendendo aos requisitos de contrato estabelecidos. Ele é geralmente escrito pelo time de desenvolvimento do serviço e é projetado para testar a integridade da comunicação entre serviços, incluindo validação de entrada, regras de negócio, comunicação com outros serviços e acesso a banco de dados.
  • Consumer Side Contract Test: Este é um tipo de teste que é usado para garantir que os clientes de um serviço estejam se comportando de acordo com o contrato estabelecido. Ele é geralmente escrito pelo time de desenvolvimento do cliente e é projetado para testar a integridade da comunicação entre o cliente e o serviço, incluindo validação de entrada, regras de negócio, comunicação com o serviço e manipulação de respostas.
  • Service Component Test: Este é um tipo de teste que é usado para garantir que um serviço esteja funcionando corretamente e atendendo aos requisitos de negócio. Ele é geralmente escrito pelo time de desenvolvimento do serviço e é projetado para testar as funcionalidades básicas do serviço, incluindo validação de entrada, regras de negócio, comunicação com outros serviços e acesso a banco de dados.

Em resumo, o Service Integration Contract Test é usado para testar a comunicação entre serviços, Consumer Side Contract Test é usado para testar a comunicação entre clientes e serviços e Service Component Test é usado para testar a funcionalidade de um único serviço.

Até aqui resolvemos os problemas de Decompor o negócio em serviços, Consultar informações em diferentes bases de dados, transacionar e testar tudo isso.

E sobre a camada de apresentação?

Para isso temos o padrão de micro fronteends.  Ele estende os conceitos de micros serviços para o mundo frontend. Este é um assunto bem complexo que só vou citar duas partes que acredito estão mais relacionadas ao micro serviços:

No alt text provided for this image

A principal diferença entre Client-side UI composition e Server-side page fragment composition é onde a composição da interface do usuário é realizada.

  • Na Client-side UI composition, a composição é realizada no lado do cliente usando frameworks JavaScript, como React, Angular ou Vue.js. Isso significa que os componentes de UI são construídos como módulos reutilizáveis, que podem ser combinados para criar diferentes páginas ou áreas de uma aplicação. Essa abordagem é interessante para aplicações de micro serviços, pois permite que cada serviço tenha sua própria interface de usuário e também permite a escalabilidade e flexibilidade, pois cada componente pode ser desenvolvido e escalado independentemente.
  • Já na Server-side page fragment composition, a composição é realizada no lado do servidor, usando frameworks de servidor, como o Spring MVC, Ruby on Rails ou Express. Isso significa que as páginas são construídas como um conjunto de fragmentos de página, como cabeçalhos, rodapés, menus e conteúdo principal. Cada fragmento é gerado pelo servidor e é composto na página final antes de ser enviada para o navegador do cliente. Essa abordagem é útil quando se deseja um controle rígido sobre o layout da página e a segurança dos dados, mas pode ser menos escalável e flexível do que a composição de UI no lado do cliente.

Com isso finalizo os padrões da camada Application patterns. Faltou resolver aqui os problemas de auditoria e métricas. Sobre estes escreverei quando o assunto for o padrão Observability.

Entre para ver ou adicionar um comentário

Outras pessoas também visualizaram

Conferir tópicos