# 5. REST Architecture ![](imgs/5-rest-architecture_0.png) --- # REST - What it actually is? Style of software architecture commonly used to create networked services REST comes from "representational state transfer" Defined by Roy Fielding in 2000 as architecture for distributed hypermedia systems. Incidentally, NOT made for web services at all Developed in parallel with HTTP1.1 While (almost) any application layer protocol can be used, REST APIs are almost always built on HTTP --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST architecture * Data and functionality are resources * Resources are accessed through URIs * Resources are acted upon by simple and well-defined operations * Clients and servers exchange representations of resources using a standardised protocol (usually HTTP) * Resources are decoupled from representations * Allows content to be accessed in a variety of formats (e.g. HTML, XML, plain text, image formats, JSON, etc.) * Resource metadata is available to be used for detecting errors, negotiate the appropriate representation format, access control, control caching, etc. * All resources are stateless --- Access control: e.g. key token validation Statelessness: every response is isolated; fulfilling requests is not dependent on any other requests client is responsible for sending the data about itself # REST - Requirements * For something to be considered RESTful, it needs to follow a set of architectural constraints * Be client-server * Client context must not be stored on server (server is stateless) * Explicitly reusable responses (cacheable) * Have an uniform interface, with the restrictions * Be designed to be a layered system (you don't need to know if you are targeting the end server directly, or something in-between) # REST constraints - Client-Server * First constraint is client-server * Separation of concerns * Separate user interaction from data * Allows independent evolvement of components; no need to rebuild server if UI needs a rework, and vice versa * Scalability by simplification of server components * Portability of the user interface across platforms --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST constraints - Statelessness * Servers must be stateless * Intended to improve visibility, reliability and scalability * Each request from the client must contain all the necessary information to understand the request * Requests cannot take advantage of stored context on the server * This means that in true RESTful services session state is stored entirely on client side * Single request can be used to determine full nature of the request * No need to manage resource usage across requests * Server can quickly free resources for other requests * Easily recover from partial errors --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST constraints - Cacheability * Client-cache-stateless-server * Statelessness enables some endpoints to always produce the same result with the same request * Responses to requests can then be explicitly marked as cacheable * Clients can reuse cached responses for the same requests * Reduces repetitive requests * Potential to eliminate some interactions completely * Trades reliability for performance, efficiency and scalability * What happens when the data updates? * At this point, we are at design rationale for the early (pre-1994) world wide web architecture --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST constraints - Uniform interface * Central distinguishing feature of REST style * REST implementations are restricted by four interface constraints * identification of resources * manipulation of resources through representations * self-descriptive messages * hypermedia as the engine of application state * Transfer information in standardised form rather than specific to application's needs * Implementations are decoupled from the services they provide * Encourage independent evolvement at the cost of efficiency --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST constraints - Layered system * Allow architecture to be composed of hierarchical layers * Last required constraint * Let components "see" only the immediate layer they are interacting with * Arbitrary amount of servers accessible by this layer * Reduce overall system complexity by restricting knowledge of the system to a single layer * Encapsulate legacy services * Protect new services from legacy clients * Hence bugs and errors in old code cannot be exploited, while still preserving functionality * Enable load balancing * Tradeoff here is added overhead and latency --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST constraints - Code-on-Demand * Optional final constraint * Client functionality is allowed to be extended by downloading and executing code in the form of applications or scripts * Goal is to simplify clients by reducing amount of pre-implemented features * Is optional in REST because of reduced visibility * Can be a problem from security viewpoint --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST elements - Resources * Basic REST abstraction is a _resource_ * Any information that can be named * Document, news article, image, collection, person, etc. * Identified with a _resource identifier_ * Commonly URI * Identifies resources interacting between components * State of a resource at a certain timestamp is called a _resource representation_ --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # REST elements - Representation * Consist of data, metadata describing it and hypermedia links * Hypermedia links help clients to transition to the next desired state * This is where the name Representational State Transfer comes from * Hypermedia means just that the controls are presented with the information, the links on web pages being the obvious example * The data format of a representation is called a _media type_ . The media type identifies how a representation should be processed by the client * Self-descriptive * Client does not need to know if the resource is a book or an employee, it should act according to the media type associated with the resource * Often leads to creating a lot of custom media types --- Fielding's paper is available online at https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm and is relatively short https://restfulapi.net/ seems like a good resource Wikipedia is plain wrong, but less wrong in English than in Finnish # RESTful APIs Note that most "REST API"s out there do not fill these requirements Often any web API on top of HTTP is incorrectly described as "RESTful" Most commonly hypermedia isn't used as the engine of application state, or the application is not really stateless, and some people outright ignore those requirements from the get go (which in case of both, technically makes the system RPC, not REST, but the name still sticks) --- This slide sucks * A REST API should be entered without prior knowledge beyond the initial URI and the appropriate media types * i.e. media types expected to be understood by all clients that might use the API * Moving forward, application state transitions are driven by client selection from server-provided choices present in the received representations * This is to keep interaction driven by in-band information * REST does not equal HTTP * As long as the REST constraints are honoured, the interface can be called RESTful --- https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven # 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: ![](imgs/5-rest-architecture_1.png) # 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 ![](imgs/5-rest-architecture_2.png) # Creating a POST Request with Postman - Example Suppose the Post method from before is routed at http://localhost:54106/api/students: ![](imgs/5-rest-architecture_3.png) # 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: ![](imgs/5-rest-architecture_4.png) # 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 ![](imgs/5-rest-architecture_5.png) # 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 Put(int id, [FromBody] Contact contact) { // Contacts = list of Contact objects, fetched from some repository List 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 ![](imgs/5-rest-architecture_6.png) # Handling HttpDelete Requests The ID is fetched from the URI [HttpDelete("{id}")] public List Delete(int id) { // Contacts = list of contact objects, fetched from some repository List 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 ![](imgs/5-rest-architecture_7.png) # 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 Patch(int id, [FromBody] JsonPatchDocument 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