Uma das novidades mais interessantes, pelo menos na minha visão, na versão atual .NET 6 são as Minimal API’s, um conceito bastante interessante onde a ideia principal é a criação de uma API de forma eficiente, com utilização de menos recursos.

 

Pode ser uma boa opção para um cenário de “microsserviços” ou, no geral, aplicativos com poucas dependências. Esse conceito vem ao encontro do crescente ou já existente modelo de criação de API’s de forma simplificada. Exemplo disso é o Python e o Express, do Node.js.

 

VANTAGENS

  • Para quem é iniciante, este modelo é muito mais simplificado e ajuda a entender conceitos básicos de uma API;
  • Reduz de forma significativa a quantidade de código, já que não há mais a necessidade de criação de filtros, roteamentos e até mesmo controladores;
  • O conceito ajuda a simplificar o código escrito, deixando-o muito mais legível.

 

DESVANTAGENS

  • O uso errado do modelo pode ser um problema, pois é preciso validar se em seu projeto faz sentido;
  • O aumento excessivo do “cs”, tendo em vista que o código basicamente por conceito deve estar todo neste arquivo;
  • A criação de alternativas para evitar muito código no “cs” vai contra o conceito, causando bagunça e dificuldades em sua manutenção ou evolução.

MÃOS À OBRA!

Abra o Visual Studio 2022 e selecione a opção “Create a New Project”.

 

 IMAGEM 1

 

Selecione a opção “ASP.NET Core Web API”.

  IMAGEM 2

 

Agora você deverá dar um nome para sua solução, indicar o local onde o projeto será criado e em seguida clicar em Next.

 

IMAGEM 3

 

Vamos utilizar a versão .NET 6 (LTS), desmarcar a opção Use Controllers (quando queremos um modelo mínimo) e clicar em Create.

  IMAGEM 4

 

De cara, já podemos observar que a estrutura do projeto já é menor à qual normalmente estamos acostumados. O projeto já traz a opção instalada do pacote do OpenApi (passo anterior, onde deixámos a opção marcada), ou, se preferirem, “Swagger”.

 IMAGEM 5

 

IMAGEM 6

 

Ou seja, com pouquíssimos passos já temos uma API pronta e funcional rodando o projeto “WeatherForecast”, modelo padrão existente nos projetos .NET.

 

Mas é claro que só isso não significa aprender sobre Minimal API’s, portanto agora vamos criar exemplos reais para de fato conseguir perceber as suas funcionalidades.

 

Primeiro, vamos ao arquivo “Program.cs excluir comentários e até mesmo os métodos do projeto inicial. O arquivo deverá ficar assim:

 

IMAGEM 7

 

A partir daqui, vamos criar uma versão um pouco mais completa. A ideia é criar um registro de clientes e utilizar o “Entity Framework Core“ para persistir os dados em uma base de dados “Sql Server.

 

Há pacotes que precisamos instalar, por isso abra o “Package Manager Console”. Caso ele não esteja disponível na parte inferior do “Visual Studio”, você pode habilitar ele pelo menu => Tools/Nuget Package Manager/Package Manager Console:

 

IMAGEM 8

 

Já no Package Manager Console, deverá digitar o seguinte comando:

 

IMAGEM 9

 

Repita o mesmo comando para os seguintes packages:

  • Install-Package Microsoft.EntityFrameworkCore
  • Install-Package Microsoft.EntityFrameworkCore.SqlServer
  • Install-Package Microsoft.EntityFrameworkCore.Tools

 

Depois vamos criar duas pastas no nosso projeto: Data e Models:

 IMAGEM 10

 

Dentro da pasta Models vamos criar nossa entidade Cliente:

 IMAGEM 11

 

Nosso cliente possui um ID, Nome, Documento e um campo para identificar se está ativo ou inativo.

 

Agora, vamos criar o nosso DbContext, que vai nos ajudar a tratar os dados com Entity Framework Core, bem como modelar a nossa tabela para o Sql Server.

 

Crie então uma classe dentro da pasta Data chamada de “MinimalApiDbContext.cs”. Neste mesmo arquivo vamos modelar a configuração necessária para nossa tabela “Clientes”. Não é um tema obrigatório, mas sempre faço, pois isso nos permite modelar campo a campo com o tipo e tamanho correto, caso contrário a tabela será criada com tipos e tamanhos padrões, portanto considero uma boa prática.

 

Ao final, esta classe deverá ficar assim:

 

IMAGEM 12

 

Bem, já chegámos longe, já configurámos nosso projeto, criámos a nossa entidade cliente, criámos nosso DbContext e configurámos nele a nossa tabela para logo mais persistir no nosso banco de dados.

 

Por falar em banco de dados, precisamos indicar para nossa API a string de conexão, que ela deve utilizar ao longo da vida da aplicação. Para isso, voltamos ao nosso arquivo “Program.cs” e adicionamos aos serviços o nosso contexto, qual a base de dados será utilizada e qual a string de conexão. Segue exemplo:

 

IMAGEM 13

 

Logo na sequência, como estamos dizendo para a aplicação que vamos utilizar a conexão chamada “DefaultConnection”, precisamos de fato incluir ela no arquivo de configuração da aplicação. Devemos para isso abrir o arquivo “appsettings.json” e incluir estas duas linhas:

 

IMAGEM 14

 

Pronto, estamos quase lá!!

 

Agora que tudo está devidamente configurado, precisamos executar a Migration, ou seja, o Entity Framework Core, mediante as nossas configurações. Vai materializar a nossa tabela no banco de dados, em dois passos:

 

1. Digite o comando “Add-Migration initial -Context MinimalApiDbContext -v:

  • Add-Migration => comando do EF Core para adicionar uma nova migração;
  • Initial => nome que dei para esta migração. Pode ser qualquer nome que facilite a identificação do que está sendo migrado/criado/alterado no banco de dados;
  • -Context => nome do contexto, que no nosso caso é o mesmo nome da classe que criámos para o contexto “MinimalApiDbContext”;
  • -v => também chamado de verbose, como o nome já diz, ele detalha mais o processo na console quando ele ocorre. É opcional, mas sempre utilizo, pois ajuda muito quando erros ocorrem no momento da migração.

2. Se tudo correr bem no passo anterior, devemos então executar o comando “Update-Database -Context MinimalApiDbContext -v”, que vai pegar os meta dados gerados na migração e criar o que configurámos no Sql Server.

 

Como podemos observar agora:

 

IMAGEM 15

 

Temos então nosso banco de dados criado e nossa tabela de Clientes. O Entity Framework Core também cria uma tabela extra chamada “__EFMigrationsHistory”, mas não vou entrar neste tópico, talvez em uma outra oportunidade.

 

COMO CRIAR ENDPOINTS?

Bem, na nossa classe “Program.cs” vamos criar um método do tipo void que vai centralizar todo o fluxo dos nossos métodos HTTP. Seria algo semelhante a uma Controller, caso precise de uma referência:

 

IMAGEM 16

 

Agora, vamos criar nosso primeiro endpoint - vou chamar ele “/clientes”. Para um entendimento geral posso dizer que os métodos HTTP, no caso de uma Minimal API, serão representados sempre por um padrão onde o início será “Map” + “método HTTP”. Por exemplo “MapGet”, “MapPut”, “MapPost” e assim por diante. Veja o exemplo:

 IMAGEM 17

 

Note que a rota é /clientes passada por parâmetro no método “MapGet” e, dentro deste método, mesmo nós também informamos o contexto e na sequência conseguimos chamar o método do nosso contexto que melhor atente a situação, que neste caso é a listagem de clientes. Conseguimos inclusivé dar nome para este endpoint “GetClientes” e uma funcionalidade interessante são as TAGS que neste caso chamei de “Clientes”. Podemos agora executar nossa aplicação com este primeiro exemplo:

 

IMAGEM 18

 

Seguindo na mesma linha, faz sentido ter um endpoint que possa servir uma requisição que queira obter um cliente específico, pelo seu ID por exemplo:

 

IMAGEM 19

 

Este exemplo mostra que a nossa rota, que agora recebe o nome /clientes/{id}, é diferente de antes. Agora também passamos para o método “MapGet” o Id que recebemos na requisição, e depois o contexto, para finalmente obter o cliente pelo método FindAsync(id). Como uma boa prática ressalto que devemos fazer alguns tratamentos como a verificação se este cliente existe e retornar a quem requisitou o código correto - no nosso caso, ou um código 200 ou um 404.

 

Como boa prática inseri também Produces, que seria equivalente ao ProducesResponseType da Controller. Ele vai ajudar a padronizar e melhorar a documentação para quem irá consumir a API e consiga entender que tipos de respostas aquele endpoint pode retornar.

 

IMAGEM 20 

 

Ok, já sabemos como criar um “Get” e um “GetById”. Vamos evoluir nossa aplicação para um “POST”.

 

Exemplo:

P.S => Aqui uma dica de ouro: existe um pacote que vamos instalar que vai-nos ajudar a fazer validações das requisições que recebemos. Vamos instalar o pacote “Install-Package MiniValidation -Version 0.6.0-pre.20220527.55” (até o momento deste artigo, a versão está em pré release, portanto deve ser executado o comando completo).

 

Caso tenham interesse em entender mais sobre o projeto, segue o link

 

Este pacote vai-nos ajudar a criar validações com base em “Data Annotations” configuradas nas nossas entidades. Vamos dar um exemplo alterando nossa classe “Clientes.cs” e incluir uma validação onde o nome do cliente deve ter no mínimo 3 caracteres:

 IMAGEM 21

 

Agora, voltamos para “Program.cs” e vamos criar nosso “MapPost”:

 IMAGEM 22

 

E aqui já percebemos algumas novidades. Na linha 49 vamos manter o padrão e chamar a rota /clientes, nosso contexto e o modelo de entrada.

 

Logo na sequência vamos usar nossa funcionalidade “MiniValidator” para tratar a validação da nossa entidade cliente. Caso algum erro ocorra, já podemos devolver o resultado para quem está consumindo a API, exemplo:

 

Request:

 

IMAGEM 23

 

Response:

 

IMAGEM 24

 

Veja que interessante: a validação com MiniValidation já cuidou de tudo e retornou a mensagem de erro, indicando onde e qual é o problema.

 

Seguindo na análise do MapPost, percebemos que ele vai persistir o dado no SqlServer. Caso tenha sucesso, vamos utilizar o recurso de Results.CreatedAtRoute("GetClientesById", new { id = cliente.Id }, cliente)”, que basicamente já vai retornar o response chamando nosso GetById, que criámos anteriormente, e faz isso utilizando o Name “.WithName("GetClientesById")”, que configurámos na obtenção do cliente por código.

 

No Sql Server:

  IMAGEM 25

 IMAGEM 26

 

O MapPut eu diria que é muito parecido com MapPost, porém a diferença clara ao consumir nosso contexto é a chamada do método de Update.

 IMAGEM 27

 

Ou seja, primeiro tento buscar o cliente no SqlServer. Caso eu encontre e consiga passar pela validação, deverá persistir o dado no SqlServer.

 

IMAGEM 28 IMAGEM 29

 

E, finalmente, temos nosso MapDelete, que é muito mais simples, bastando apenas encontrar o registro desejado para verificar sua existência, e efetuar a remoção do registro no SqlServer.

 

Exemplo:

IMAGEM 30

 

Temos nosso registro excluído com sucesso.

 

E pronto! O link do código fonte está no meu GitHub (se quiser dar um star lá, eu agradeço 😊).

 

LINKS ÚTEIS

Partilha este artigo