Rest API vs HTTP API – Are your REST APIs really REST APIs?

Let’s say you want to create a REST API using a framework like Spring Boot.

You create a class annotated with @RestController.

And then you create APIs using @RequestMapping/@GetMapping/@PostMapping annotation.

Are these really REST APIs?

No.

They are just HTTP APIs.

What is the difference between the two?

HTTP is one of the ways information can be transported across the internet.

It is a communication protocol.

Any API you develop using this protocol is just a HTTP API and not a REST API,

For an API to be classified as a REST API it needs to have certain features.

And these are just architectural patterns and not defined standards.

And so Spring Boot or any other framework does not enforce these features . It is up to the developer to implement them.

Let’s deep dive into this:

The term REST (Representational State Transfer) was coined by Roy T. Fielding (this is his blog link). He expresses his frustration over ordinary HTTP APIs being called as REST APIs in his blog.

What is REST?

REST represents a collection of resources.

So you need to design your application in such a way that they are exposed as a set of resources.

You can retrieve resources through GET method.

You can insert new resource/ update existing resource using POST method .

Every response should also have links to help the client perform other operations on the resource.

How to identify a REST API?

One of the ways to identify whether an API is a RESTful API or not , is to use Richardson Maturity Model , a popular model used for the same purpose (link).

According to this model there are four levels which an API need to pass through to be accepted as RESTful API.

For simplicity sake , let’s assume that we are going to use HTTP to implement REST API. (It can also be implemented using other protocols like SOAP)

And also the request and response are of JSON data type.(REST supports other content types like XML as well)

Advertisements

Here are the four levels:

Level 0: Same URI , Same HTTP Method

In this level you just use a single URI to make HTTP calls.

Also you use a single HTTP method (POST).

For example , let’s take an example of ordering food over an online food delivering platform (like Swiggy in India)

The app has HTTP API(s) exposed to be consumed by UI interface or other interfaces like mobile app.

At this level , the app has a single URI which is used for all the purposes.

To search for a restaurant you might have a HTTP API like this:

HttpMethod : POST

URI : http://myfoodapp.com/deliveryservice

Request :

{

   "servicename":"searchrestaurants",
    "location":"chennai"
}

Response:

{
  "servicename":"searchrestaurants",
   [

       {
          "name":"Dindigul Thalapakatti",
          "items":[..]  
      },
  {
          "name":"Madras Cafe",
          "items":[..]  
      },
    ]
}

If you want to view a particular food item , you might use the same URI with a different “servicename”

Http Method: POST

URI: http://myfoodapp.com/deliveryservice

Request:

{
   "servicename":"viewfood",
    "foodname":"rasagulla"
}

Response:

{

    "servicename":"viewfood",
    "foodname":"rasagulla",
    "cost": 100
    "stock":10
    ....
    ....
}

Same URI

Same Http Method

The different functionalities are identified by using a special identifier (“servicename”) in the request.

Any one calling your REST API should know the “servicename” to identify a functionality and also the request structure to perform any operation. They need to get this information via email or by pinging you.

And they are not aware of what other operations they could perform on your app.

And if they want to say order an item , you need to communicate to them explicitly how to do it (what the URI is , what the request structure should be like )

And that is not a characteristic of a proper REST API!

Now let’s move to the next level.

Advertisements

Level 1: Different URI, Same Http Method

In this level , you think using a single URI is too restrictive.

Why not use different URI s to identify different functionality.

So you create new URIs for different functionalities.

In the above example , you get rid of the “servicename” and create new URI for each functionality.

Also remember REST is a collection of resources.

So each URI should represent a resource.

So you start using proper resource names.

For searching restaurants you might use something like this:

HttpMethod: POST

URI : http://myfoodapp.com/restaurants

Request:

{

    "location":"Chennai"
}

Response:

{

   [

       {
          "name":"Dindigul Thalapakatti",
          "items":[..]  
      },
  {
          "name":"Madras Cafe",
          "items":[..]  
      },
    ]
}

“restaurants” represent a list of restaurant resources.

And to view a food item you might use a different URI like this:

http://myfoodapp.com/food/rasagulla

To add a new food item , you might use :

http://myfoodapp.com/food

Similarly to represent an order you might use a URI like this:

http://myfoodapp.com/order/1

where 1 represents the order id.

To represent status of an order you might use something like this:

http://myfoodapp.com/order/1/status

Any URI in your application should represent a resource and not a functionality.

This is crucial. You can just look at the URI and say that it represents a particular resource.

If the client wants to update the resource , enough information should be present in the response when you retrieved the resource.

For example,

The below URI:

http://myfoodapp.com/order/1

should return all the details of an order so that client can update that order later using this information.

To summarize:

Different URIs.

URIs represent resources and not method names.

Same HTTP Method (POST).

Every response has enough information to represent the state of that resource.

Again you do not know what other operations are exposed by the app and how to navigate to different resources.

Now let’s move on to level 2:

Advertisements

Level 2: Different URI, Different Http Methods and Http Status

In this level , you make use of HTTP Verbs like GET and POST.

For retrieving a resource you always use GET http method.

For inserting a new resource you use POST http method.

For updating a new resource also you can use POST method.

There are arguments over using PUT , PATCH and DELETE methods amongst experts and POST method can be used to perform all these operations.

So in the above example , to get the list of restaurants , you can use a GET method instead of POST:

Http Method: GET

http://myfoodapp.com/restaurants?location=chennai

The reason to use GET to retrieve resources is that GET is idempotent.

It means it wont change the state of a resource, no matter how many times you fire the GET request , it is not going to change the values of the resource , whereas if you use POST it means the state of the resource can be changed.

So for making any change to the resource or insert a new one you use POST request:

http://myfoodapp.com/food

Request:

{
   "name":"rasagulla",
    "cost":100,
    "stock":10,
   "description":"....."
 
}

And once a request is made , the response should also carry proper HTTP response status code:

200 – if the resource was retrieved successfully

201 – A new resource is created

409- Some conflict in updating the resource (some one else is updating it at the same time etc)

404 – resource is not found

etc.

To summarize,

Different URIs

Different Http Methods

Different Http Status.

Still you cannot navigate through the entire set of resources exposed by the app.

This is where hypermedia comes in and we move to level 3.

Advertisements

Level 3: Different URI, Different Http Methods , Hypermedia.

When you go to a website , you usually land on the home page.

And from the home page you can navigate to different links by just clicking on them.

You don’t have to call the one who made the website and ask them

“Hey I want to find a particular food item to order”

You just click the meaningful link on the website.

They are intuitive.

This is exactly how a real REST API should look like for any client consuming your REST API.

There should be an initial URI through which anyone should be able to navigate to all other resources in your application.

This feature is called HATEOS (HyperMedia as the engine of application state)

In the above example , if you fire a GET request to the below URI:

http://myfoodapp.com

it should list the URIs representing all the resources in the application.

HttpMethod: GET

URI : http://myfoodapp.com

Response:

{
   "links":
        {
             "restaurants":  {
                 "listrestaurants": "http://myfoodapp.com/restaurants?location=chennai",
                  "addrestaurant":"http://myfoodapp.com/restaurant",
                   "viewrestaurant":"http://myfoodapp.com/12345"
               }

                "food":{

                 ......
                     }

                  "order":{
                      .....
                         }

        }

}

Client just need to visit the “home” URI and they can find out all other URIs.

Also whenever they view a resource , the operations supported on the resource should also be displayed as links.

For example , when client views a restaurant , the other URIs related to restaurants should be returned:

http://myfoodapp.com/restaurants/123

{

       "name":"Madras Cafe",
         "location":"Chennai",

               ....

                ....

         "links":{

               "addrestaurant":"http://myfoodapp.com/restaurant", 
                       "viewitemsinrestaurant":"http://myfoodapp.com/restaurant/12345/items",

         }

}

The links provide a way to navigate through the different operations performed on the resource.

This is called hypermedia just like hyperlinks on websites.

Without this a HTTP API cannot be called a REST API.

Image an UI team is working on the interface and they need to call your services .

Instead of creating APIs according to the functionalities required in the project (which keeps changing and getting added) , if the service developer could develop the services as a collection of resources and hypermedia as above , the interdependency between UI team and service team can be reduced. They can work quite independently.

Service developer can just share the “home” URI and UI can start calling the APIs with little information from the service developer.

And that is when your Http API can be called a REST API!

Advertisements

Also REST API need to satisfy 5 mandatory constraints:

Client server architecture:

Code related to user interface should be on the UI application.

And only code related to the business and data should be on the server and exposed via REST API.

Statelessness:

There should be no session related information stored on the server.

A RESTful API is stateless whereas a HTTP API can be stateful (You can store session information in cookies and send it to the server)

Cacheability:

A REST API response should be cacheable so that repeated hits to the server can be avoided when required. You do this by calling GET APIs for retrieving data (Since GET is an idempotent operation the response can be safely cached). And also by making use of Cache-Control header in HTTP response.

Layered System:

Can you introduce an API gateway between client and server application and your app still works seamlessly?

Then your application is layered.

UI need not bother about whether it is hitting an API gateway or the real service. That is abstracted away. That is one of the features a RESTful API should have.

Uniform Interface:

Is your REST application exposed as a collection of resources which can be easily identified and modified ?

Do they have proper URIs to represent their state ? to add a new resource ? to modify an existing resource?

Do they provide enough information to modify a resource (while retrieving the resource)?

Do they have hypermedia to navigate to different links to perform different operations on the resource.

In short if they are on level 3 in Richardson’s Maturity Model they have a uniform interface .

That’s it!

References:

Richardson’s Maturity Model – https://www.crummy.com/writing/speaking/2008-QCon/act3.html

Martin Fowler’s perspective – https://martinfowler.com/articles/richardsonMaturityModel.html

Roy T. Fielding’s (creator of REST) blogpost – https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Wikipedia – https://en.wikipedia.org/wiki/Representational_state_transfer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s