Exercício – Adicionar um controlador
Um controlador é uma classe pública com um ou mais métodos públicos conhecidos como ações. Por convenção, um controlador é colocado no diretório Controllers da raiz do projeto. As ações são expostas como pontos de extremidade HTTP no controlador da API Web.
Criar um controlador
Selecione a pasta Controladores no Visual Studio Code e adicione um novo arquivo chamado PizzaController. cs.
Um arquivo de classe vazio chamado PizzaController.cs é criado no diretório Controladores. O nome do diretório Controladores é uma convenção. O nome do diretório vem da arquitetura model-view-controller que a API Web usa.
Observação
Por convenção, os nomes de classe do controlador apresentam Controlador como sufixo.
Adicione o código a seguir a Controllers/PizzaController.cs. Salve suas alterações.
using ContosoPizza.Models; using ContosoPizza.Services; using Microsoft.AspNetCore.Mvc; namespace ContosoPizza.Controllers; [ApiController] [Route("[controller]")] public class PizzaController : ControllerBase { public PizzaController() { } // GET all action // GET by Id action // POST action // PUT action // DELETE action }
Conforme você aprendeu anteriormente, essa classe deriva de
ControllerBase
, a classe base para trabalhar com solicitações HTTP no ASP.NET Core. Ele também inclui os dois atributos padrão sobre os quais você aprendeu:[ApiController]
e[Route]
. Assim como antes, o atributo[Route]
define um mapeamento para o token[controller]
. Como essa classe de controlador é nomeadaPizzaController
, esse controlador manipula as solicitações parahttps://localhost:{PORT}/pizza
.
Obter todas as pizzas
O primeiro verbo REST que precisamos implementar é GET
, em que um cliente pode obter todas as pizzas da API. Você pode usar o atributo [HttpGet]
interno para definir um método que retorne as pizzas de nosso serviço.
Substitua o comentário // GET all action
em Controllers/PizzaController.cs pelo seguinte código:
[HttpGet]
public ActionResult<List<Pizza>> GetAll() =>
PizzaService.GetAll();
A ação anterior:
- Responde apenas ao verbo HTTP
GET
, conforme indicado pelo atributo[HttpGet]
. - Retorna uma instância de
ActionResult
do tipoList<Pizza>
. O tipoActionResult
é a classe base para todos os resultados da ação no ASP.NET Core. - Consulta o serviço para todas as pizzas e retorna automaticamente os dados com um valor
Content-Type
igual aapplication/json
.
Recuperar apenas uma pizza
O cliente também pode querer solicitar informações sobre uma pizza específica em vez de toda a lista. Você pode implementar outra ação GET
que requer um parâmetro id
. Você pode usar o atributo [HttpGet("{id}")]
interno para definir um método que retorne as pizzas de nosso serviço. A lógica de roteamento registra [HttpGet]
(sem id
) e [HttpGet("{id}")]
(com id
) como duas rotas diferentes. Você pode então criar uma ação separada para recuperar um único item.
Substitua o comentário // GET by Id action
em Controllers/PizzaController.cs pelo seguinte código:
[HttpGet("{id}")]
public ActionResult<Pizza> Get(int id)
{
var pizza = PizzaService.Get(id);
if(pizza == null)
return NotFound();
return pizza;
}
A ação anterior:
- Responde apenas ao verbo HTTP
GET
, conforme indicado pelo atributo[HttpGet]
. - Requer que o valor do parâmetro
id
seja incluído no segmento da URL apóspizza/
. Lembre-se, o atributo[Route]
do nível do controlador definiu o padrão/pizza
. - Consulta o banco de dados para uma pizza que corresponde ao parâmetro
id
fornecido.
Cada instância de ActionResult
usada na ação anterior é mapeada para o código de status HTTP correspondente na tabela a seguir:
ASP.NET Core resultado da ação |
Código de status HTTP | Descrição |
---|---|---|
Ok está implícito |
200 | Um produto que corresponde ao parâmetro id fornecido existe no cache na memória.O produto está incluído no corpo da resposta no tipo de mídia, conforme definido no cabeçalho da solicitação HTTP accept (JSON por padrão). |
NotFound |
404 | Um produto que corresponde ao parâmetro id fornecido não existe no cache na memória. |
Compilar e executar o novo controlador
Compile e inicie a API Web executando o seguinte comando:
dotnet run
Testar o controlador com um arquivo HTTP
Abrir ContosoPizza.http
Adicione um novo GET para chamar o ponto de extremidade
Pizza
sob o separador ###:GET {{ContosoPizza_HostAddress}}/pizza/ Accept: application/json ###
Selecione o comando Enviar Solicitação acima dessa nova chamada GET.
O comando anterior retorna uma lista de todas as pizzas em JSON:
HTTP/1.1 200 OK Connection: close Content-Type: application/json; charset=utf-8 Date: Wed, 17 Jan 2024 16:57:09 GMT Server: Kestrel Transfer-Encoding: chunked [ { "id": 1, "name": "Classic Italian", "isGlutenFree": false }, { "id": 2, "name": "Veggie", "isGlutenFree": true } ]
Para consultar apenas uma pizza, você pode fazer outra solicitação
GET
, mas passar um parâmetroid
usando o seguinte comando:GET {{ContosoPizza_HostAddress}}/pizza/1 Accept: application/json ###
O comando anterior retorna
Classic Italian
com a seguinte saída:HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 21:57:57 GMT Server: Kestrel Transfer-Encoding: chunked { "id": 1, "name": "Classic Italian", "isGlutenFree": false }
Nossa API também lida com situações em que o item não existe. Chame a API novamente, mas passe um parâmetro pizza
id
inválido usando o seguinte comando:GET {{ContosoPizza_HostAddress}}/pizza/5 Accept: application/json ###
O comando anterior retorna um erro
404 Not Found
com a seguinte saída:HTTP/1.1 404 Not Found Content-Type: application/problem+json; charset=utf-8 Date: Fri, 02 Apr 2021 22:03:06 GMT Server: Kestrel Transfer-Encoding: chunked { "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4", "title": "Not Found", "status": 404, "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00" }
Agora que você terminou de implementar os verbos GET
. Na próxima unidade, você pode adicionar mais ações a PizzaController
para dar suporte a operações CRUD em dados de pizza.
Opcional: Testar o controlador com o REPL (Read-Eval-Print Loop) HTTP da Linha de Comando
Abra o terminal
httprepl
existente ou um novo terminal integrado do Visual Studio Code selecionando Terminal>Novo Terminal no menu principal.Conecte-se à API Web executando o seguinte comando:
httprepl https://localhost:{PORT}
Outra opção é executar o seguinte comando a qualquer momento enquanto
HttpRepl
estiver em execução:connect https://localhost:{PORT}
Para ver o ponto de extremidade de
Pizza
recém-disponível, execute o seguinte comando:ls
O comando anterior detecta todas as APIs disponíveis no ponto de extremidade conectado. Ele deve exibir o seguinte código:
https://localhost:{PORT}/> ls . [] Pizza [GET] WeatherForecast [GET]
Vá até o ponto de extremidade
Pizza
executando o seguinte comando:cd Pizza
O comando anterior mostra uma saída das APIs disponíveis para o ponto de extremidade
Pizza
:https://localhost:{PORT}/> cd Pizza /Pizza [GET]
Faça uma solicitação
GET
noHttpRepl
usando o seguinte comando:get
O comando anterior retorna uma lista de todas as pizzas em JSON:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 21:55:53 GMT Server: Kestrel Transfer-Encoding: chunked [ { "id": 1, "name": "Classic Italian", "isGlutenFree": false }, { "id": 2, "name": "Veggie", "isGlutenFree": true } ]
Para consultar apenas uma pizza, você pode fazer outra solicitação
GET
, mas passar um parâmetroid
usando o seguinte comando:get 1
O comando anterior retorna
Classic Italian
com a seguinte saída:HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 21:57:57 GMT Server: Kestrel Transfer-Encoding: chunked { "id": 1, "name": "Classic Italian", "isGlutenFree": false }
Nossa API também lida com situações em que o item não existe. Chame a API novamente, mas passe um parâmetro pizza
id
inválido usando o seguinte comando:get 5
O comando anterior retorna um erro
404 Not Found
com a seguinte saída:HTTP/1.1 404 Not Found Content-Type: application/problem+json; charset=utf-8 Date: Fri, 02 Apr 2021 22:03:06 GMT Server: Kestrel Transfer-Encoding: chunked { "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4", "title": "Not Found", "status": 404, "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00" }
Retorne ao terminal
dotnet
na lista suspensa no Visual Studio Code e desligue a API Web selecionando Ctrl+C no teclado.
Agora que você terminou de implementar os verbos GET
. Na próxima unidade, você pode adicionar mais ações a PizzaController
para dar suporte a operações CRUD em dados de pizza.