Numa arquitetura centrada no domínio coloca-se o modelo de domínio bem no centro da arquitetura, enquanto uma arquitetura baseada na base de dados é centrada no modelo de dados.
O modelo de domínio representa o modelo mental dos utilizadores e os casos de uso resolvem os seus problemas. O domínio está no centro e à sua volta está a camada de aplicação. Já a camada apresentação e persistência são detalhes e todas as dependências apontam para o domínio.
As camadas são partições da aplicação que representam diferentes níveis de abstração que suportam o princípio da responsabilidade única (single responsability principle), e permitem repartir a aplicação por unidades de complexidade fáceis de manter.
Esta arquitetura moderna reparte-se por 4 (quatro) camadas:
- Apresentação: interface de utilizador com a aplicação
- Aplicação: contém os casos de uso
- Domínio: contém apenas a lógica de domínio
- Infraestrutura: interface com a base de dados e outras infraestruturas
Nesta arquitetura, as dependências são invertidas e aplica-se o princípio da inversão de dependência (dependency inversion principle). A abstração não deve depender dos detalhes, mas sim os detalhes da abstração.
A limitação do contexto é o reconhecimento de um âmbito contextual específico com um domínio específico e esta arquitetura encaixa-se perfeitamente para o construir e delimitar com interfaces bem definidas e, assim, subdividir modelos de domínio de grande dimensão. Particionar aplicações grandes em unidades independentes, autónomas, de alta coesão e baixo acoplamento que comunicam entre si de modo seguro e escalável. Refiro-me aos micro serviços. Por definição, um micro serviço é uma componente de alta coesão, baixo acoplamento, autónoma e independente, que representa um contexto de negócio de uma aplicação.
Mas quem como Martin Fowler para falar acerca de micro serviços.
PASSAR À PRÁTICA
Agora é passar à prática através de uma arquitetura orientada ao domínio para consumir um serviço web. Qual é o serviço? É um serviço dedicado a factos sobre gatos.
Existem vários exemplos na web sobre arquitetura orientado ao domínio e sobre micro serviços, mas vou aplicá-la aqui para consumir um serviço web. Este serviço web disponibiliza factos sobre gatos, o https://catfact.ninja/fact. A solução é desenvolvida em .Net Core.
O domínio é o CatFact. Na camada de aplicação colocamos o foco nos casos de uso do sistema, no entanto, neste caso, vou manter o número de camadas o mais pequeno possível, uma vez que se pretende apenas consultar factos sobre gatos sem mais lógica de negócio.
Vou exemplificar como invocar uma web API usando a Clean Architecture do Uncle Bob. É usado um wrapper para encapsular as chamadas a serviços web e devolver as respostas.
Criar nova solução com as camadas orientadas ao domínio:
Pasta Domain
Pasta Infrastructure
Ao Domain adiciona-se o projeto do tipo biblioteca com o Core:
Pasta Entities
Pasta Interfaces
À Infrastructure adiciona-se o projecto do tipo biblioteca de nome HttpClientServices com o HTTP Client do CatFacts:
Pasta CatFacts
A pasta Interfaces comporta as interfaces intrínsecas aos CatFactServices.
Uma vez criadas as entidades que definem as entidades de domínio e referenciado o projeto Core pela biblioteca HttpClientServices, define-se o HttpClientWrapper e o CatFactService.
Um projeto do tipo Console para testar a web API client:
E já está!
Mas pode trazer-se a esta experiência uma camada de serviços lógicos e disponibilizar a nossa própria web API. Nesta camada, o serviço funciona como um wrapper da aplicação e disponibiliza as funcionalidades através de uma API com a qual a UI pode interagir.
Portanto, a camada de serviço está repartida por duas componentes físicas: o cliente e o servidor.
Vamos experimentar os serviços HTTP do ReactJS (cliente) e os controllers do ASP.NET Core (servidor).
Os serviços do ReactJS e os controllers do ASP.NET Core são bastante coesos. Os métodos destes serviços comunicam diretamente com os endpoints dos controllers do ASP.NET Core.
Adiciona-se o projeto do tipo ASP.NET Core Web Application de nome WebApp com o template de fábrica.
Define-se o CatFactController
Executa-se a web API e visualiza-se a página de documentação swagger.
Sucesso!
Agora, experimentar conhecer factos sobre gatos com o colorido do ReactJS, mas usando a WebApp construída anteriormente a pretexto.
O cliente React tem a estrutura basilar:
Na qual se aplica a seguinte sequência de comandos no diretório clientapp para conseguir uma aplicação React básica
- npm init
- npm install react react-dom
- npm i --save-dev webpack webpack-dev-server webpack-cli
- npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react html-webpack-plugin
Configurações e mais configurações para a renderização React:
.babelrc
webpack.config.js
O index.html com CSS para o colorido
index.js com o PoC React
O comando npm run start corre o projeto React e carrega a aplicação no browser.
Se houver erro CORS, a extensão CORS Unblock desbloqueia o problema. Mas, atenção, usar apenas no desenvolvimento aplicacional.
A solução usada como exemplo está disponível no GitHub.