REST - Representational State Transfer

July 08, 2020

TLDR

Usually, when people speak about REST APIs they mean a web API that uses the HTTP request methods (POST, GET, PUT, DELETE, etc.) to modify or access the state of a resource.

Individual resources are identified using URIs.

For example, a list of all users:

https://webservice.com/api/users

and the user with the id 3049485:

https://webservice.com/api/users/3049485

Now with REST you usually use one of the HTTP methods on the resource you want to modify/access.

For example, you could use the DELETE request method somewhere in your client to delete the individual user like this:

const res = await axios({
      method: 'delete',
      url: `api/user/3049485`,
    });

That’s it for the TLDR. If you want a more in-depth explanation of REST keep reading below.

REST

REST is an acronym for REpresentational State Transfer.

REST is a software architectural style that defines a set of rules that can be used for designing web APIs.

When an API follows the six constraints that define REST, then this API can be called RESTful.

Here are the six rules:

1. Client-server architecture

Client and Server should be separated. By keeping the user interface and the backend separated, we improve the portability of the user interface across multiple platforms and improve scalability by simplifying the server components.

2. Stateless

Communication must be stateless. This means that the server does not store any session data. For example, the server does not know if a user is logged in. It does not know what the last request of a user was.

The server only knows the information that is contained in the current request.

3. Cache

Every response must be labeled as cacheable or non-cacheable. If a response is cacheable, then a client cache is given the right to reuse that response laster.

4. Uniform Interface

The central feature that distinguishes REST architectural style from other network-based styles is its emphasis on a uniform interface between components.

Resource identification in requests

Individual resources are identified in requests using URI’s.

For example, a list of all users:

https://webservice.com/api/users

and the user with the id 3049485:

https://webservice.com/api/users/3049485

In this example, the resource user is identified with the id 3049485 in the request.

Resource manipulation through representations

When a client gets the current state of a resource (representation) it has enough information to modify or delete the resource.

For example, you get the user from the API like this:

https://webservice.com/api/users/3049485

This should now give you all the information to modify or delete the user. In this case, the API should return all the information about the user.

{
  "id": "3049485",
  "type": "user",
  "username": "luke123",
  "age": "22",
  "gender": "male"
}

Self-descriptive messages

A self-descriptive message is one that contains all the information that the recipient needs to understand it.

In case of a web API, the API returns the Media-Type in the Response Header

Content-Type: application/json

Now the client knows it must parse the JSON that gets returned from the API.

Hypermedia as the engine of application state (HATEOAS)

This is where most web APIs fail to follow the constraints of REST. According to this constraint, the API should behave similarly to a website.

The API should return Links that would allow a REST client to be able to dynamically discover all the available resources it needs.

For example, you get the user from the API like this:

https://webservice.com/api/users/3049485

The API should then provide you with links for all other actions on that resource.

{
  "username": "luke123",
  "age": "22",
  "gender": "male",
  "links": {
    "friends": "/users/3049485/friends",
    "wife": "/users/3049485/wife"
  }
}

Now let’s say luke does not have friends - I know it’s sad - what would the response then look like?

{
  "username": "luke123",
  "age": "22",
  "gender": "male",
  "links": {
    "wife": "/users/3049485/wife"
  }
}

The link to “friends” is missing because what actions wich are possible varies on the state of the resource.

Also, JSON does not support any links out of the box, and we need to inform the client otherwise - e.g. with documentation - how to use the links.

According to the REST definition, this feature should be defined in the media type itself, and not by documentation.

You can see that 99% of APIs are not following this constraint and are therefore not REST APIs according to the definition of Roy Fielding.

You could call these APIs RESTish or REST without HATEOAS.