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.

17 KiB

5. REST Architecture


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

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 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

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 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 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