You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
7.5 KiB
Markdown
257 lines
7.5 KiB
Markdown
# 5. REST Architecture
|
|
|
|
# HTTP Methods for RESTful APIs
|
|
|
|
* You have so far implemented GET and POST methods for reading resources from the API and creating new ones to it
|
|
* All the primary methods for following the uniform interface requirement are __GET, POST, PUT, PATCH __ and __DELETE__
|
|
* Others exist, but these are by far most commonly used
|
|
* These methods correspond to __CRUD __ operations __Create__ , __Read__ , __Update __ and __Delete__
|
|
* CRUD describes what is done to a resource after a request is sent
|
|
|
|
# HTTP Methods for RESTful APIs (continued)
|
|
|
|
The primary HTTP request methods with descriptions:
|
|
|
|
| __Method__ | __Attribute__ | __Description__ |
|
|
| :-: | :-: | :-: |
|
|
| GET | [HttpGet] | _Read _ a representation of a resource |
|
|
| POST | [HttpPost] | _Create _ new resources |
|
|
| PUT | [HttpPut] | Fully _Update _ an existing resource |
|
|
| PATCH | [HttpPatch] | Partially _Update _ an existing resource |
|
|
| DELETE | [HttpDelete] | _Delete _ a resource |
|
|
|
|
[https://www.restapitutorial.com/lessons/httpmethods.html](https://www.restapitutorial.com/lessons/httpmethods.html)
|
|
|
|
# Handling HttpPost Requests
|
|
|
|
Remember, that HTTP requests can include a content body
|
|
|
|
In ASP.NET, this content is assigned to a variable with the [FromBody] attribute:
|
|
|
|
[HttpPost]
|
|
|
|
public string[] Post([FromBody] string someContent)
|
|
|
|
{
|
|
|
|
// someContent holds the content of the request body
|
|
|
|
return new string[] { text };
|
|
|
|
}
|
|
|
|
Note that the [FromBody] attribute can only be used on one parameter
|
|
|
|
However, nothing prevents you from using a custom type variable
|
|
|
|
# Handling HttpPost Requests (continued)
|
|
|
|
ASP.NET deserializes the request content body into an object:
|
|
|
|
public class Student
|
|
|
|
{
|
|
|
|
public int Id { get; set; }
|
|
|
|
public string Name { get; set; }
|
|
|
|
}
|
|
|
|
// In controller class:
|
|
|
|
[HttpPost]
|
|
|
|
public Contact Put(int id, [FromBody] Contact contact)
|
|
|
|
{
|
|
|
|
// Contacts = list of Contact objects, fetched from some repository
|
|
|
|
Contacts.Add(contact);
|
|
|
|
return contact;
|
|
|
|
}
|
|
|
|
# Creating a POST Request with Postman
|
|
|
|
* ASP.NET knows to deserialize the content if the content type is set to JSON in the HTTP requests __headers__
|
|
* Headers are optional parameters that can be included in every HTTP request
|
|
* Headers are set in Key-Value format
|
|
* When creating a request in Postman, to inform the server what type of content was just sent, add a new key "Content-Type" and set its value to "application/json" in the _Headers _ tab:
|
|
|
|

|
|
|
|
# Creating a POST Request with Postman (continued)
|
|
|
|
After setting the header,
|
|
|
|
select the Body tab,
|
|
|
|
change the content type to raw,
|
|
|
|
select JSON from the dropdown menu, and
|
|
|
|
insert the content in JSON format
|
|
|
|

|
|
|
|
# Creating a POST Request with Postman - Example
|
|
|
|
Suppose the Post method from before is routed at http://localhost:54106/api/students:
|
|
|
|

|
|
|
|
# Exercise 1: Creating a POST Endpoint
|
|
|
|
Continue working on CourseAPI.
|
|
|
|
Create a Post method and endpoint which adds a new course to the list in the repository, with a running ID. Content and Author values are obtained from the request body:
|
|
|
|

|
|
|
|
# HTTP PUT
|
|
|
|
Use PUT to replace an existing resource, e.g. an element in a list, with a new one
|
|
|
|
The ID of the resource to be replaced should be in the request URI
|
|
|
|
The information about the new resource should be in the request body like in POST requests
|
|
|
|

|
|
|
|
# Handling HttpPut Requests
|
|
|
|
The ID is fetched from the URI and the contents from the request body
|
|
|
|
Filtering is used to copy all objects from the original list except for the new contact object, which comes from body
|
|
|
|
[HttpPut("{id}")]
|
|
|
|
public List<Contact> Put(int id, [FromBody] Contact contact)
|
|
|
|
{
|
|
|
|
// Contacts = list of Contact objects, fetched from some repository
|
|
|
|
List<Contact> updatedList = Contacts.Select(c => c.Id != id ? c : contact).ToList();
|
|
|
|
Contacts = updatedList;
|
|
|
|
return updatedList;
|
|
|
|
}
|
|
|
|
# Exercise 2: Creating a PUT Endpoint
|
|
|
|
* In CoursesController class, create a method for PUT requests with the URI api/courses/{id}
|
|
* The ID of the course to be replaced with should be in the request URI and the contents of the new course should be in the request body.
|
|
* The method should replace the corresponding course from the Courses list in the repository with the new course.
|
|
* The method should return the updated Courses list (for testing purposes)
|
|
* Return a 404 status code if a course with the corresponding ID does not exist
|
|
* Test with Swagger/Postman
|
|
|
|
# HTTP DELETE
|
|
|
|
Use DELETE to delete an existing resource, e.g. an element in a list
|
|
|
|
The ID of the resource to be deleted should be in the request URI
|
|
|
|
As with GET method, a body is not needed
|
|
|
|

|
|
|
|
# Handling HttpDelete Requests
|
|
|
|
The ID is fetched from the URI
|
|
|
|
[HttpDelete("{id}")]
|
|
|
|
public List<Contact> Delete(int id)
|
|
|
|
{
|
|
|
|
// Contacts = list of contact objects, fetched from some repository
|
|
|
|
List<Contact> updatedList = Contacts.Where(c => c.Id != id).ToList();
|
|
|
|
Contacts = updatedList;
|
|
|
|
return Contacts;
|
|
|
|
}
|
|
|
|
# Exercise 3: Creating a DELETE Endpoint
|
|
|
|
* Continue working on CourseAPI.
|
|
* Create an endpoint for DELETE requests with the URI api/courses/{id}
|
|
* The ID of the course should be fetched from the URI
|
|
* The corresponding course should be removed from the list of courses in the repository
|
|
* The method should return the updated Courses list (for testing purposes)
|
|
* Return a 404 status code if a course with the corresponding ID does not exist
|
|
* Test with Postman
|
|
|
|
# HTTP PATCH
|
|
|
|
* Use PATCH to partially update a resource
|
|
* I.e. update some value inside of a resource
|
|
* This saves some resources as only a part of a resource has to be sent instead of an entire document (as opposed to PUT requests)
|
|
* Sending and handling PATCH requests with ASP.NET requires some extra work and the use of a third party package: [http://jsonpatch.com/](http://jsonpatch.com/)
|
|
|
|
# HTTP PATCH (continued)
|
|
|
|
* To handle PATCH requests in a standardized way, install and add the following NuGet packages to your project:
|
|
* Microsoft.AspNetCore.JsonPatch
|
|
* Microsoft.AspNetCore.Mvc.NewtonsoftJson
|
|
* Then, change the following line in Program.cs (ASP.NET 5: Startup.cs)...
|
|
* builder.Services.AddControllers();
|
|
* … to this:
|
|
* builder.Services.AddControllers().AddNewtonsoftJson();
|
|
|
|
The body of the PATCH request needs to be in the following form:
|
|
|
|
[{ "op": "replace", "path": "/propertyName", "value": "newValue"}]
|
|
|
|
Use the URI to specify the ID of the resource to update
|
|
|
|

|
|
|
|
# Handling HttpPatch Requests
|
|
|
|
The ID is fetched from the URI
|
|
|
|
The property and its new value are specified in the body, which is retrieved as JsonPatchDocument
|
|
|
|
PATCH is operated on the targeted object
|
|
|
|
[HttpPatch("{id}")]
|
|
|
|
public List<Contact> Patch(int id, [FromBody] JsonPatchDocument<Contact> patchDocument)
|
|
|
|
{
|
|
|
|
// Contacts = list of contact objects, fetched from some repository
|
|
|
|
var contact = Contacts.FirstOrDefault(c => c.Id == id);
|
|
|
|
if(contact != null){
|
|
|
|
patchDocument.ApplyTo(contact);
|
|
|
|
}
|
|
|
|
return Contacts;
|
|
|
|
}
|
|
|
|
# Exercise 4: Creating a PATCH Endpoint
|
|
|
|
* Continue working on CourseAPI.
|
|
* Create an endpoint for PATCH requests with the URI api/courses/{id}
|
|
* The ID of the course should be fetched from the URI
|
|
* The corresponding course should be updated according to the JSON PATCH document in the request body
|
|
* The method should return the updated Courses list (for testing purposes)
|
|
* Return a 404 status code if a course with the corresponding ID does not exist
|
|
* Test with Swagger/Postman: try to change the number of credits for some course
|