Exercise - Implement CRUD operations
Let's continue extending our web API controller to add the ability to create (POST
), update (PUT
), and delete (DELETE
) pizza from our inventory.
Add a pizza
Let's enable a pizza to be added through the web API by using a POST
method.
Replace the // POST action
comment in Controllers/PizzaController.cs with the following code:
[HttpPost]
public IActionResult Create(Pizza pizza)
{
PizzaService.Add(pizza);
return CreatedAtAction(nameof(Get), new { id = pizza.Id }, pizza);
}
The preceding action:
- Responds only to the HTTP
POST
verb, as denoted by the[HttpPost]
attribute. - Inserts the request body's
Pizza
object into the in-memory cache.
Note
Because the controller is annotated with the [ApiController]
attribute, it's implied that the Pizza
parameter will be found in the request body.
The first parameter in the CreatedAtAction
method call represents an action name. The nameof
keyword is used to avoid hard-coding the action name. CreatedAtAction
uses the action name to generate a location
HTTP response header with a URL to the newly created pizza, as explained in the previous unit.
Modify a pizza
Now, let's enable a pizza to be updated through the web API by using a PUT
method.
Replace the // PUT action
comment in Controllers/PizzaController.cs with the following code:
[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();
}
The preceding action:
- Responds only to the HTTP PUT verb, as denoted by the
[HttpPut]
attribute. - Requires that the
id
parameter's value is included in the URL segment afterpizza/
. - Returns
IActionResult
, because theActionResult
return type isn't known until runtime. TheBadRequest
,NotFound
, andNoContent
methods returnBadRequestResult
,NotFoundResult
, andNoContentResult
types, respectively.
Note
Because the controller is annotated with the [ApiController]
attribute, it's implied that the Pizza
parameter will be found in the request body.
Remove a pizza
Finally, let's enable a pizza to be removed through the web API by using a DELETE
method.
Replace the // DELETE action
comment in Controllers/PizzaController.cs with the following code:
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var pizza = PizzaService.Get(id);
if (pizza is null)
return NotFound();
PizzaService.Delete(id);
return NoContent();
}
The preceding action:
- Responds only to the HTTP
DELETE
verb, as denoted by the[HttpDelete]
attribute. - Requires that the
id
parameter's value is included in the URL segment afterpizza/
. - Returns
IActionResult
because theActionResult
return type isn't known until runtime. TheNotFound
andNoContent
methods returnNotFoundResult
andNoContentResult
types, respectively. - Queries the in-memory cache for a pizza that matches the provided
id
parameter.
Remember to save the Controllers/PizzaController.cs file before proceeding,
Build and run the finished web API
Build and start the web API by running the following command:
dotnet run
Test the finished web API with HTTP files
Reopen the ContosoPizza.http file.
Make a
POST
request to add a new pizza inHttpRepl
by using the following command:POST {{ContosoPizza_HostAddress}}/pizza/ Content-Type: application/json { "name": "Hawaii", "isGlutenFree": false } ###
The preceding command returns the newly created pizza:
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 }
Update the new
Hawaii
pizza to aHawaiian
pizza with aPUT
request by using the following command:PUT {{ContosoPizza_HostAddress}}/pizza/3 Content-Type: application/json { "id": 3, "name": "Hawaiian", "isGlutenFree": false } ###
The preceding command returns the following output that indicates success:
HTTP/1.1 204 No Content Connection: close Date: Wed, 17 Jan 2024 17:07:30 GMT Server: Kestrel
To verify that the pizza was updated, rerun the
GET
action by using the following command:GET {{ContosoPizza_HostAddress}}/pizza/3 Accept: application/json ###
The preceding command returns the newly updated pizza:
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 }
Our API can also delete the newly created pizza through the
DELETE
action if you run the following command:DELETE {{ContosoPizza_HostAddress}}/pizza/3 ###
The preceding command returns a
204 No Content
result for success:HTTP/1.1 204 No Content Date: Fri, 02 Apr 2021 23:30:04 GMT Server: Kestrel
To verify that the pizza was removed, rerun the
GET
action by using the following command:GET {{ContosoPizza_HostAddress}}/pizza/ Accept: application/json ###
The preceding command returns the original pizzas as results:
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 } ]
You're now finished implementing and testing a newly created web API built with ASP.NET Core.
Optional: Test the finished web API with Command Line HTTPREPL
Reopen the existing
httprepl
terminal, or open a new integrated terminal from Visual Studio Code by selecting Terminal > New Terminal from the main menu.If you opened a new terminal, connect to the web API by running the following command:
httprepl https://localhost:{PORT}
Alternatively, run the following command at any time while
HttpRepl
is running:connect https://localhost:{PORT}
Go to the
Pizza
endpoint by running the following command:cd Pizza
Run the following command to see the new actions on the Pizza API:
ls
The preceding command shows an output of available APIs for the
Pizza
endpoint:https://localhost:{PORT}/Pizza> ls . [GET|POST] .. [] {id} [GET|PUT|DELETE]
Make a
POST
request to add a new pizza inHttpRepl
by using the following command:post -c "{"name":"Hawaii", "isGlutenFree":false}"
The preceding command returns the newly created pizza:
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 }
Update the new
Hawaii
pizza to aHawaiian
pizza with aPUT
request by using the following command:put 3 -c "{"id": 3, "name":"Hawaiian", "isGlutenFree":false}"
The preceding command returns the following output that indicates success:
HTTP/1.1 204 No Content Date: Fri, 02 Apr 2021 23:23:55 GMT Server: Kestrel
To verify that the pizza was updated, rerun the
GET
action by using the following command:get 3
The preceding command returns the newly updated pizza:
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 }
Our API can also delete the newly created pizza through the
DELETE
action if you run the following command:delete 3
The preceding command returns a
204 No Content
result for success:HTTP/1.1 204 No Content Date: Fri, 02 Apr 2021 23:30:04 GMT Server: Kestrel
To verify that the pizza was removed, rerun the
GET
action by using the following command:get
The preceding command returns the original pizzas as results:
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 } ]
You're now finished implementing and testing a newly created web API built with ASP.NET Core.