Arquitetura hexagonal

Arquitetura de sistemas: uma preocupação que todos desenvolvedores possuem ao desenvolver uma nova aplicação. A arquitetura de um sistema é o que irá mapear as funcionalidades dos componentes da sua aplicação, junto com a interação do usuário com estes componentes.

Hoje, iremos falar de uma arquitetura em específico: a arquitetura hexagonal. 

Mostrar os prós e contras desta arquitetura, e fazer um repasse de cada “pedaço” de sua estrutura.

Características

A arquitetura hexagonal possui como principal característica dividir as classes de um sistema em dois grupos:

  • Adaptadores: classes que estão relacionadas à infraestrutura, tecnologia e integrações com sistemas externos
  • Domínio: classe que está diretamente relacionada com as regras de negócio do sistema.

Um diagrama completo de uma arquitetura hexagonal seguindo o Domain Driven Design.

Na imagem acima vemos que tudo que está dentro de Domain Services está relacionado com as regras de negócio do sistema. Ou seja, o Domínio, e tudo que está no application service (incluindo os adapters e ports) estão relacionados com os Adaptadores.

Estrutura

Como vimos no desenho lá em cima, nesta arquitetura existem abstrações com alguns nomes “meio estranhos”. Então vamos passar pelos mais importantes e entender qual a funcionalidade de cada um deles.

Domain Services

Esta parte da aplicação é a mais importante de todas, pois é nela que estão as regras de negócio do sistema.

Entities

É onde ficam as entidades do sistema. Elas irão encapsular as regras de negócio e os atributos da aplicação.

Uma entidade pode ser um objeto com propriedades e métodos ou pode ser definida como uma estrutura de dados e funções.

Events

É onde ficam os eventos que irão “fazer alguma coisa” com as entidades do Domain. Nessa parte ficarão métodos que executarão uma tarefa, como por exemplo: “comprar algodão doce na padaria”.

Um domínio também pode ser separado em subdomínios para uma extração melhor dos eventos da sua aplicação.

Services

São camadas da aplicação que irão executar funções lógicas em mais de uma entidade. 

Se você precisa ler uma informação de uma entidade e atualizar outra entidade, esta execução estará em um service específico. 

Como no exemplo:

Application services

Aqui ficarão as interações com camadas externas da aplicação.

Services

Esta camada também pode ser chamada de “Workflow Services”, “Use Cases” dentre outros. 

Ela irá orquestrar os passos para concluir uma operação e pode conter regras de negócio não relacionadas ao domínio da aplicação. A camada utilizará o conceito de ports sempre que for executar processos de recursos externos.

Ports

São interfaces que definem contratos que são implementados pelos adapters da infraestrutura. Essas interfaces possuem uma série de regras/métodos que a infraestrutura deverá conter para realizar sua execução. 

Por exemplo, uma ports de um banco de dados:

Command/Queries

É um princípio onde todo método deverá ser um Comando que irá executar uma ação ou uma Query que irá retornar alguma informação para quem a está chamando. 

Métodos somente devem retornar valor se eles não possuírem efeitos colaterais e seguirem as regras da transparencia referêncial. Os services da camada Application Services deverão ser um command ou um query.

Infrastructure

Aqui é onde o Tony Stark faz a festa. É onde vamos plugar funcionalidades, ferramentas e tecnologias na nossa aplicação, como Banco de Dados, Interfaces de comunicação, Logs dentre outros.

Adapter

Adaptadores da infraestrutura será a nossa ponte para integrar com interfaces externas. 

Todo adaptador deverá seguir uma regra definida em uma PORT que foi criada na camada Application Services

Exemplos de adapters que poderiam ser utilizados em uma aplicação com nodeJS: axios, nodemail etc.

Repository

Assim como adapters, são classes que executam ações externas. Mais especificamente, o repository irá acessar bancos de dados e encapsular lógicas para obter/gravar informações no mesmo. 
Um exemplo de como seria um repository a partir do exemplo de port lá de cima:

Interfaces

Esta é a camada mais externa da sua aplicação. É onde o cliente irá consumir/inserir informações, e onde estarão as interfaces de input/output direto com o cliente.

Controller

São classes que irão receber solicitações, disparar casos de uso e apresentar resultados de volta para o cliente. Exemplo de controllers:

  • HTTP Controller é o mais comum. São controllers que recebem chamadas http como POST e GET.
  • Event Controller são controllers que recebem eventos de serviços externos como Redis, Kafka, RabbitMQ dentre outros.
  • Dto são interfaces de transferência de dados, elas definirão contratos entre a API e o cliente. Podem ser interfaces de request ou de responses.

Mas qual a vantagem disso tudo?

Vantagens 😆🧘👍🌈🌞

  • Facilidade de plugar/desplugar frameworks, tecnologias e bancos de dados externos, gerando uma independência na aplicação.
  • Facilmente escalável e testável.
  • A arquitetura facilita que várias equipes/desenvolvedores trabalhem no mesmo projeto sem esbarrar em alterações um dos outros. “no conflict”
  • Fácil de adicionar novas funcionalidades. A dificuldade de adicionar novas funcionalidades para a aplicação é constante e relativamente pequena, principalmente quando o projeto já está grande.
  • É fácil extrair e separar partes da aplicação para micro serviços.

Desvantagens 😥👺👎😈🌑

  • É uma arquitetura complexa e depende de um bom conhecimento em princípios de desenvolvimento, como SOLID, clean architecture e DDD. Desenvolvedores menos experientes poderão ter dificuldades em trabalhar em um projeto com uma arquitetura hexagonal.
  • Aplicações menores terão mais problemas do que soluções em utilizar esta arquitetura 🤔. Logo, não é recomendado para aplicações com operações simples e poucos adaptadores. O foco maior da arquitetura hexagonal são as aplicações que possuem vários adaptadores externos e múltiplas funcionalidades.

Avalie e planeje bem as escolhas que você faz antes de começar a desenvolver um projeto utilizando arquitetura hexagonal. 

Considerar as vantagens e desvantagens da arquitetura faz muita diferença para o futuro da aplicação.

Isso é tudo pessoal!

Bibliografia

https://github.com/Sairyss/domain-driven-hexagon

https://badia-kharroubi.gitbooks.io/microservices-architecture/content/patterns/tactical-patterns/domain-application-infrastructure-services-pattern.html

Autor: João Pedro

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *