ASP.NET Core Web API - Definindo o roteamento
Neste artigo veremos como definir o roteamento em aplicações ASP .NET Core Web API. |
O roteamento
na ASP.NET Core é o processo de mapeamento de requisições recebidas para a
lógica do aplicativo que reside nos controladores e métodos Actions.
A ASP.NET Core mapeia a requisição recebida com base nas rotas configuradas no seu aplicativo e, para cada rota, você pode definir configurações específicas, como valores padrão, manipuladores de mensagens, restrições e assim por diante.
Nos projetos
.NET Core, por padrão, os Controllers são decorados com métodos CRUD,
especificando os respectivos verbos de ação HTTP: Get, Post, Put e Delete.
Existem algumas maneiras de controlar o roteamento em um aplicativo ASP.NET
Core, e, as mais comuns são:
Roteamento convencional: Aa rota é determinada com
base em convenções definidas em modelos de rota que, em tempo de execução,
mapearão requisições para controladores e Actions (métodos).
Roteamento baseado em atributos: A rota é
determinada com base nos atributos que você define em seus controladores e
métodos. As definições nos atributos irão realizar o mapeamento para as Actions
do controlador.
Neste artigo, vamos nos concentrar no roteamento baseado em atributos usado pelas Web API.
A principal diferença com o roteamento das aplicações Web API sobre as aplicações MVC é que elas usam o método HTTP, não o caminho do URI, para selecionar a Action. O roteamento de atributos também usa verbos HTTP para definir a Action dos métodos do controlador conforme a requisição.
No caso das Web APIs a recomendação é usar o roteamento baseado em atributos que permite anexar uma rota, como um atributo, a um controlador ou método Action específico, e, isso é feito usando o atributo [Route].
O roteamento baseado em atributos oferece controle preciso sobre os URIs, ao contrário do roteamento por convenção, e, em um cenário de recursos hierárquicos eles podem ser facilmente alcançados pelo Roteamento de Atributos, sem comprometer a escalabilidade das APIs.
Beneficíos do roteamento
Veremos a seguir exemplos práticos de roteamento basedo em atributos.
Criando o projeto Web API no VS 2019 Community
Vamos criar uma aplicação ASP .NET Core Web Application usando o template API no Visual Studio 2019 Community chamada APi_Roteamentos;
Abra o VS 2019 Community e selecione : Create a new Project
Selecionando em Language : C#, Platform: All Platforms e em Project Type: web podemos selecionar o template ASP .NET Core Web Application:
A seguir vamos informar o nome do projeto: APi_Roteamentos , sua localização e nome da solução, que é o mesmo do projeto;
Finalmente selecione a plataforma .NET Core e ASP .NET Core 2.2 e o template API.
Marque a opção para configurar HTTP e não vamos usar Autenticação:
Ao final teremos um projeto Web API com um controlador chamado ValuesController definido na pasta Controllers.
Analisando o controlador ValuesController
Abaixo temos o código do controlador ValuesController que é gerado por padrão no projeto API:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; }
// GET api/values/5 // POST api/values // PUT api/values/5 // DELETE api/values/5 |
Observe que a classe ValuesController é decorada com os atributos:
[Route("api/[controller]")]
[ApiController]
O token [ApiController] melhora a experiência do desenvolver habilitando diversos recursos como:
O token [controller] substitui os valores do nome do controlador a partir da Action ou classe onde a rota esta definida.
Assim a URI que vai acessar o método [HttpGet] sem parâmetro é api/values, e a que vai acessar o segundo método [HttpGet("{id}")] é a api/values/1.
Considere os métodos Actions a seguir:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; }
// POST api/values } |
Para o trecho de código fornecido acima, temos as mesmas URIs (api/values) mas os verbos HTTP são diferentes:
Isso faz com que o roteamento da API da Web seja diferente do roteamento MVC.
Vejamos a seguir alguns padrões de roteamentos que podem ser usados nas WEB APIs:
1- Versionamento
No próximo exemplo, "Get /api/values/v1/" será roteado para o primeiro método Get enquanto que "Get /api/values/v2/" será roteado para o segundo método Get:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { [HttpGet("v1")] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; }
[HttpGet("v2")] |
Aqui os métodos são iguais mas possuem um roteamento diferente que atua como um versionamento do método que possui duas versões v1 e v2 definidas em HttpGet.
2- Sobrecarga de URI
Neste exemplo, "id" é um parâmetro que pode ser passado como número, enquanto que "valor" será mapeado para uma coleção.
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { [HttpGet("{id}")] public ActionResult<IEnumerable<string>> Get(int id) { return new string[] { "value1", "value2" }; }
[HttpGet("valor")] |
Dessa forma temos que :
3- Parâmetros com múltiplos tipos
Neste exemplo, "id" é um parâmetro que pode ser passado como o número ou como uma string:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { [HttpGet("{id:int}")] public ActionResult<IEnumerable<string>> Get(int id) { return new string[] { "value1", "value2" }; }
[HttpGet("id:alpha")] |
Dessa forma temos que :
4- Múltiplos Parâmetros
Neste exemplo, "id" e "autorid" são parâmetros que podem ser passados como um número inteiro:
[Route("api/[controller]")] [ApiController] public class AutoresController : ControllerBase { [HttpGet("{id:int}/autor/{autorid:int}")] public ActionResult<IEnumerable<string>> Get(int id, int autorid) { return new string[] { "value1", "value2" }; } .... } |
Assim temos que :
a URI: Get api/livros/1/autor/5 onde 1 mapeia para o ‘id’ e ‘5’ para 'autorid' no método Action.
5- Múltiplas Rotas
O roteamento de atributos nos permite definir várias rotas para o mesmo controlador, Action ou Método.
Veja o exemplo a seguir:
[Route("api/[controller]")] [ApiController] public class FilmesController : ControllerBase { [HttpPut("compra")] [HttpPost("checkout")] public ActionResult<List<Filme>> PedidoFilme(..) { return ... } .... } |
Conforme mostrado no exemplo, o método "PedidoFilme" retorna algum valor usando a classe de modelo "Filme".
O método define duas rotas:
Ambos estão se
referindo ao mesmo método.
Nesse caso, os URIs abaixo seriam correspondentes às rotas:
URI 1 -> Put api/filmes/compra
URI 2 -> Post api/filmes/checkout
Podemos também definir múltiplas rotas usando o atributo Route conforme abaixo:
[HttpGet("")]
[HttpGet("Home")]
[HttpGet("Home/Index")]
public string Index() {
return "Método Index";
}
|
Neste exemplo o mapeamento vai funcionar assim:
URL | Corresponde ? | Analisado como |
---|---|---|
/ |
Sim |
Controller=Home Action=Index |
/Home | Sim |
Controller=Home Action=Index |
/Home/Index |
Sim |
Controller=Home Action=Index |
/Ola/Mundo | Não |
6- Restrição de Rotas
A restrição de rota fornece controle sobre os parâmetros correspondentes usados na rota. A sintaxe para definir parâmetros na rota é "{parameter: constraint}".
Veja o exemplo a seguir:
[Route("api/[controller]")] [ApiController] public class FilmesController : ControllerBase { [HttpGet("api/constraint/{id:int:min(1)}")] public ActionResult<IEnumerable<string>> Get(int id) { return ... } .... } |
A rota que mapeia para o método é : api/constraint/1
Somente o
valor inteiro será roteado para o método 'Get' respondendo com um recurso
válido. Qualquer outro valor não inteiro não será atendido pelo método. Assim,
a uri : api/constraint/abc não será roteada.
Aqui, poderia haver um problema. Vejamos...
Se o cliente chamar , api/constraint/0 , o request seria roteado para o método Get, o que está errado.
Para contornar esse problema, podemos adicionar outra restrição ao parâmetro para aceitar um valor maior que zero. Isso pode ser alcançado incluindo a restrição "min(1)", no qual 1 é argumento aceito pela restrição "min". Argumentos podem ser aceitos entre parênteses "()"
O namespace Microsoft.AspNetCore.Routing.Constraints define um conjunto de classes que podem ser usadas para definir restrições individuais.
Abaixo uma tabela das restrições que verificam o tipo de dados:
constraint | Inline | Classe | Descrição |
---|---|---|---|
int | {id:int} | IntRouteConstraint | Restringe um parâmetro de rota para representar apenas valores inteiros de 32 bits |
alpha | {id:alpha} | AlphaRouteConstraint | Restringe um parâmetro de rota para conter apenas letras minúsculas ou maiúsculas de A a Z no alfabeto inglês. |
bool | {id:bool} | BoolRouteConstraint | Restringe um parâmetro de rota para representar apenas valores booleanos. |
datetime | {id:datetime} | DateTimeRouteConstraint | Restringe um parâmetro de rota para representar apenas valores de DateTime. |
decimal | {id:decimal} | DecimalRouteConstraint | Restringe um parâmetro de rota para representar apenas valores decimais. |
double | {id:double} | DoubleRouteConstraint | Restringe um parâmetro de rota para representar apenas valores de ponto flutuante de 64 bits |
float | {id:float} | FloatRouteConstraint | Corresponde a um valor flutuante válido (na invariant culture) |
guid | {id:guid} | GuidRouteConstraint | Corresponde a um valor válido de Guid |
Essas são algumas das possibilidades mostrando como o roteamento pode ser flexível.
Pegue o projeto completo aqui: Api_AnalyzersDemo.zip
Ninguém jamais viu a Deus; o Deus unigênito
(Jesus), que está no seio do Pai, é quem o revelou.
João
1:17,18
Referências:
ASP .NET Core 2 - MiniCurso Básico - Macoratti
ASP .NET Core MVC - CRUD básico com ADO .NET
ASP .NET Core - Implementando a segurança com .
ASP .NET Core - Iniciando com ASP .NET Core MVC e .
ASP .NET Core MVC - Criando um site com MySql e EF ..
ASP .NET Core - Gerenciador de Despesas Pessoais com ..
Minicurso ASP .NET Core 2.0 - Apresentando MVC - YouTube
ASP .NET Core - Configurando o ambiente de ...
ASP .NET Core e EF Core - Configurando o ambiente
ASP .NET Core - Como configurar o AutoMapper