Exercício – implementar operações CRUD
Vamos continuar estendendo nosso controlador de API Web para adicionar a capacidade de criar (POST
), atualizar (PUT
) e excluir (DELETE
) pizzas de nosso estoque.
Adicionar uma pizza
Vamos permitir que uma pizza seja adicionada por meio da API da Web usando um método POST
.
Substitua o comentário // POST action
em Controllers/PizzaController.cs pelo seguinte código:
[HttpPost]
public IActionResult Create(Pizza pizza)
{
PizzaService.Add(pizza);
return CreatedAtAction(nameof(Get), new { id = pizza.Id }, pizza);
}
A ação anterior:
- Responde apenas ao verbo HTTP
POST
, conforme indicado pelo atributo[HttpPost]
. - Insere o objeto
Pizza
do corpo da solicitação no cache na memória.
Observação
Como o controlador está anotado com o atributo [ApiController]
, está implícito que o parâmetro Pizza
será encontrado no corpo da solicitação.
O primeiro parâmetro na chamada de método CreatedAtAction
representa um nome de ação. A palavra-chave nameof
é usada para evitar hard-coding do nome da ação. CreatedAtAction
usa o nome da ação para gerar um cabeçalho de resposta HTTP location
com uma URL para a pizza recém-criada, conforme explicado na unidade anterior.
Modificar uma pizza
Agora, vamos permitir que uma pizza seja atualizada por meio da API da Web usando um método PUT
.
Substitua o comentário // PUT action
em Controllers/PizzaController.cs pelo seguinte código:
[HttpPut("{id}")]
public IActionResult Update(int id, Pizza pizza)
{
if (id != pizza.Id)
return BadRequest();
var existingPizza = PizzaService.Get(id);
if(existingPizza is null)
return NotFound();
PizzaService.Update(pizza);
return NoContent();
}
A ação anterior:
- Responde apenas ao verbo HTTP PUT, conforme indicado pelo atributo
[HttpPut]
. - Requer que o valor do parâmetro
id
seja incluído no segmento da URL apóspizza/
. - Retorna
IActionResult
porque o tipo de retornoActionResult
não é conhecido até o runtime. Os métodosBadRequest
,NotFound
eNoContent
retornam os tiposBadRequestResult
,NotFoundResult
eNoContentResult
respectivamente.
Observação
Como o controlador está anotado com o atributo [ApiController]
, está implícito que o parâmetro Pizza
será encontrado no corpo da solicitação.
Remover uma pizza
Por fim, vamos permitir que uma pizza seja removida por meio da API da Web usando um método DELETE
.
Substitua o comentário // DELETE action
em Controllers/PizzaController.cs pelo seguinte código:
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var pizza = PizzaService.Get(id);
if (pizza is null)
return NotFound();
PizzaService.Delete(id);
return NoContent();
}
A ação anterior:
- Responde apenas ao verbo HTTP
DELETE
, conforme indicado pelo atributo[HttpDelete]
. - Requer que o valor do parâmetro
id
seja incluído no segmento da URL apóspizza/
. - Retorna
IActionResult
porque o tipo de retornoActionResult
não é conhecido até o runtime. Os métodosNotFound
eNoContent
retornam os tiposNotFoundResult
eNoContentResult
, respectivamente. - Consulta o cache na memória para uma pizza que corresponde ao parâmetro
id
fornecido.
Lembre-se de salvar o arquivo Controllers/PizzaController.cs antes de continuar,
Compilar e executar a API Web concluída
Compile e inicie a API Web executando o seguinte comando:
dotnet run
Testar a API Web concluída com arquivos HTTP
Reabra o arquivo ContosoPizza.http.
Faça uma solicitação
POST
para adicionar uma nova pizza aHttpRepl
usando o seguinte comando:POST {{ContosoPizza_HostAddress}}/pizza/ Content-Type: application/json { "name": "Hawaii", "isGlutenFree": false } ###
O comando anterior retorna a pizza recém-criada:
HTTP/1.1 201 Created Connection: close Content-Type: application/json; charset=utf-8 Date: Wed, 17 Jan 2024 17:03:02 GMT Server: Kestrel Location: http://localhost:5192/Pizza/3 Transfer-Encoding: chunked { "id": 3, "name": "Hawaii", "isGlutenFree": false }
Atualize a nova pizza
Hawaii
para uma pizzaHawaiian
com uma solicitaçãoPUT
usando o seguinte comando:PUT {{ContosoPizza_HostAddress}}/pizza/3 Content-Type: application/json { "id": 3, "name": "Hawaiian", "isGlutenFree": false } ###
O comando anterior retorna a seguinte saída que indica êxito:
HTTP/1.1 204 No Content Connection: close Date: Wed, 17 Jan 2024 17:07:30 GMT Server: Kestrel
Para verificar se a pizza foi atualizada, execute novamente a ação
GET
usando o seguinte comando:GET {{ContosoPizza_HostAddress}}/pizza/3 Accept: application/json ###
O comando anterior retorna a pizza recém-atualizada:
HTTP/1.1 200 OK Connection: close Content-Type: application/json; charset=utf-8 Date: Wed, 17 Jan 2024 17:09:01 GMT Server: Kestrel Transfer-Encoding: chunked { "id": 3, "name": "Hawaiian", "isGlutenFree": false }
Nossa API também pode excluir a pizza recém-criada por meio da ação
DELETE
se você executar o seguinte comando:DELETE {{ContosoPizza_HostAddress}}/pizza/3 ###
O comando anterior retorna um resultado
204 No Content
para êxito:HTTP/1.1 204 No Content Date: Fri, 02 Apr 2021 23:30:04 GMT Server: Kestrel
Para verificar se a pizza foi removida, execute novamente a ação
GET
usando o seguinte comando:GET {{ContosoPizza_HostAddress}}/pizza/ Accept: application/json ###
O comando anterior retorna as pizzas originais como resultados:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 23:31:15 GMT Server: Kestrel Transfer-Encoding: chunked [ { "id": 1, "name": "Classic Italian", "isGlutenFree": false }, { "id": 2, "name": "Veggie", "isGlutenFree": true } ]
Você terminou de implementar e testar uma API Web recém-criada com ASP.NET Core.
Opcional: Testar a API Web concluída com o HTTPREPL da linha de comando
Abra novamente o terminal
httprepl
existente ou um novo terminal integrado do Visual Studio Code selecionando Terminal>Novo Terminal no menu principal.Se você abriu um novo terminal, 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}
Vá até o ponto de extremidade
Pizza
executando o seguinte comando:cd Pizza
Execute o seguinte comando para ver as novas ações na API de Pizza:
ls
O comando anterior mostra uma saída das APIs disponíveis para o ponto de extremidade
Pizza
:https://localhost:{PORT}/Pizza> ls . [GET|POST] .. [] {id} [GET|PUT|DELETE]
Faça uma solicitação
POST
para adicionar uma nova pizza aHttpRepl
usando o seguinte comando:post -c "{"name":"Hawaii", "isGlutenFree":false}"
O comando anterior retorna a pizza recém-criada:
HTTP/1.1 201 Created Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 23:23:09 GMT Location: https://localhost:{PORT}/Pizza?id=3 Server: Kestrel Transfer-Encoding: chunked { "id": 3, "name": "Hawaii", "isGlutenFree": false }
Atualize a nova pizza
Hawaii
para uma pizzaHawaiian
com uma solicitaçãoPUT
usando o seguinte comando:put 3 -c "{"id": 3, "name":"Hawaiian", "isGlutenFree":false}"
O comando anterior retorna a seguinte saída que indica êxito:
HTTP/1.1 204 No Content Date: Fri, 02 Apr 2021 23:23:55 GMT Server: Kestrel
Para verificar se a pizza foi atualizada, execute novamente a ação
GET
usando o seguinte comando:get 3
O comando anterior retorna a pizza recém-atualizada:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 23:27:37 GMT Server: Kestrel Transfer-Encoding: chunked { "id": 3, "name": "Hawaiian", "isGlutenFree": false }
Nossa API também pode excluir a pizza recém-criada por meio da ação
DELETE
se você executar o seguinte comando:delete 3
O comando anterior retorna um resultado
204 No Content
para êxito:HTTP/1.1 204 No Content Date: Fri, 02 Apr 2021 23:30:04 GMT Server: Kestrel
Para verificar se a pizza foi removida, execute novamente a ação
GET
usando o seguinte comando:get
O comando anterior retorna as pizzas originais como resultados:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 23:31:15 GMT Server: Kestrel Transfer-Encoding: chunked [ { "id": 1, "name": "Classic Italian", "isGlutenFree": false }, { "id": 2, "name": "Veggie", "isGlutenFree": true } ]
Você terminou de implementar e testar uma API Web recém-criada com ASP.NET Core.