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.

https://www.luisdev.com.br/2020/09/29/clean-architecture-com-asp-net-core-parte-1/
https://www.luisdev.com.br/2020/10/05/clean-architecture-com-asp-net-core-parte-2/
https://www.luisdev.com.br/2020/12/23/clean-architecture-com-asp-net-core-parte-3/
https://www.luisdev.com.br/2021/03/07/clean-architecture-com-asp-net-core-parte-4/

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

Código-fonte aqui.


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.


Quer alavancar sua carreira como Desenvolvedor(a) .NET?

Opa, aqui é o Luis Felipe (LuisDev), criador do blog LuisDev.

Além de Desenvolvedor .NET Sênior, eu sou instrutor de mais de 700 alunos e também tenho dezenas de mentorados.

Conheça o com mais de 800 video-aulas sobre C# e desenvolvimento de APIs com ASP NET Core, Microsserviços com ASP NET Core, Arquitetura de Software, Computação em Nuvem, SQL, HTML, CSS e JavaScript, JavaScript Intermediário, TypeScript, Desenvolvimento Front-End com Angular, e Desenvolvimento Front-end com React. Diversos mini-cursos disponíveis aos alunos e atualizações gratuitas.

Suporte dedicado, e comunidade de centenas de alunos.

Completo e online, destinado a profissionais que querem dar seu próximo passo em sua carreira como desenvolvedores .NET.

Clique aqui para ter mais informações e garantir sua vaga


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!