Clean Architecture com ASP.NET Core – Parte #5

Aprenda a como implementar o Clean Architecture (ou Arquitetura Limpa) com ASP.NET Core nessa série de artigos.

Nessa #5 parte irei falar sobre a camada API/Interface, explicando seus objetivos e descrevendo seus componentes.

Código-fonte aqui.


Quer ser notificado sobre os próximos artigos, lives semanais, eventos e treinamentos? Entre no canal LuisDev no Telegram!


A camada API/Interface

Antes de falar dos seus componentes, vou explicar porque eu digo API/Interface e não somente API ou Interface.

Você pode implementar o Clean Architecture (ou Arquitetura Limpa) tanto em projetos de API, quanto em projetos MVC. A diferença, é que em ASP.NET Core elas vão ter leves diferenças.

Em um projeto MVC, você teria a camada Interface, contendo as Views e Controllers. Já no projeto API, você teria a camada API, contendo os Controllers e outros componentes. Sendo assim, dependendo do tipo de projeto que utilize, a nomenclatura da camada poderá mudar, podendo usar nomes como App ou API.

Os componentes dessa camada geralmente são:

  • Controllers e Actions
  • Filters
  • Views (caso seja MVC)

Dependendo da estrutura que utilize, ainda poderá ter a configuração de Injeção de dependência se não estiver sendo tratada em sua respectiva camada de origem, como no caso de Repositórios, e Serviços de Aplicação e Infraestrutura.

Controllers e Actions

Controllers são classes que herdam de ControllerBase, e que vão conter os pontos de acesso (ou endpoints) da API. Cada endpoint é representado por uma Action, que basicamente é um método.

O ideal é que as Actions sejam o mais simples possível. Elas deveriam receber os dados da requisição, e com o mínimo de trabalho possível delegar para a camada Application, idealmente delegando o objeto recebido diretamente para ela.

Em APIs se espera que as Actions retornem respostas HTTP, como Ok (código 200), NoContent (204), BadRequest (400), entre outras. Essa expectativa existe devido a adoção extensiva do padrão REST na Web, que aumenta a legibilidade e facilidade de integração de serviços na Web. Já no padrão MVC, é retornada uma View junto com os dados necessários para seu uso.

No projeto de exemplo da série, o Controller relativo a Unidade ficou igual abaixo.

UnidadesController com os endpoints definidos

Filters

Filters são componentes do ASP NET Core que permitem a execução de código em diferentes etapas do processamento de uma requisição. Por exemplo, é possível executar código antes ou depois da execução de uma Action. Alguns exemplos de uso são:

  • Validar dados de entrada de API
  • Salvar registro da requisição (log)
  • Tratar dados de uma exceção e formatar para retorno

Por eles estarem muito acoplados ao framework, se recomenda colocá-los dentro da camada mais externa, a API/Interface!

Um exemplo de Filter a ser utilizada na aplicação é o de validação, em conjunto com a biblioteca FluentValidation. Mostro exatamente como fazer isso, passo a passo, no artigo referenciado abaixo.

Fluent Validations e ASP.NET Core: Criando um Filter de validação da entrada de sua API

Views

No padrão MVC, as Views são responsáveis por lidar com a apresentação dos dados da aplicação, e da interação do usuário. Basicamente, ela é composta por código HTML e de sintaxe Razor.

O foco do artigo e dessa série de artigos é o de desenvolvimento de APIs. Devido a isso, não incluí Views no projeto desenvolvido.


Juntando tudo e concluindo

Para facilitar desenvolver o exemplo, eu fiz algumas concessões do ponto de vista de desenho de código. Por exemplo, criei um método em Unidade para definir o Id, para que eu pudesse criar uma estrutura em memória possível de testar o fluxo de execução da arquitetura limpa sem precisar utilizar um banco de dados.

A estrutura de projetos, com a API incluída, fica que nem a imagem abaixo.

Solução Completa do Projeto

Lembre-se de configurar a injeção de dependência corretamente! Em nosso caso, foi preciso adicionar as interfaces e implementações de Repositórios e Serviços de Aplicação. Como concessão em nosso exemplo, o Repositório foi configurado com o tempo de vida Singleton, para persistir as alterações em memória entre requisição. Em condições normais, ele seria Scoped.


Já pensou nos resultados incríveis que você pode ter com o meu acompanhamento em sua carreira, com foco em te ajudar a definir, acompanhar e conquistar seus objetivos? Sejam eles a respeito de especialização técnica, promoções de cargo, reconhecimento, conquistas financeiras, reconhecimento de comunidade e/ou carreira internacional.

Tenho um Programa de Mentoria em Grupo focado em desenvolvedores .NET, e estou recebendo aplicações. Se tiver interesse real em contar com minha ajuda nisso, clique aqui e preencha o formulário.


Para consolidar o que foi aprendido, indico baixar o repositório do projeto e debugar entre as camadas. E após isso, tentar criar um projeto próprio seguindo essa arquitetura. A prática leva a perfeição!

Espero que essa série tenha sido útil. Bons estudos!