The REST you know!! Or not? Part 2

In my previous post about REST you could read about the basics of a REST interface. In this post I will try to explain the HTTP Verbs that you should use with REST in detail.

Reponse type

Responses of the REST API can be any form, but mostly used are XML and JSON. In this blog I will use JSON as request and response types. But in principle it does not matter if you use XML or JSON.

Safe and Idempotent

Every time that you communicate with a REST API some sort of operation is executed on the server. This can be a request operation, but can also be adding, updating or deleting objects. When an operation does not change any data on the server side an operation can be called 'safe'. This means that if you execute the operation multiple times no data will be changed on the server and the data is 'safe'. If an operation can be executed multiple times and the outcome of the operation is the same after the first operation this is called 'idempotent'. 

Create a new object (POST)

The POST verb is used for creating objects. The image below shows an example of a POST for creating a Rental. The example below shows the POST with a rental object as body (JSON object). In the rental object you can see the Id of the Car and the Id of the Customer that rents the car. There are also other properties like startdate and many more. The POST is executed on the '/rentals' resource uri.

 

 

If the POST is successful the server will respond with a HTTP Status Code 201 (Created). The location of the newly created object is returned as Uri in the Location Header of the response. By executing the location URI the objects information can be requested.

If you POST a second time with same information 2 identical objects will be created with a different identifier. If your object model has constraints on the data whereby the object cannot exists multiple times the server may respond with a HTTP Status Code 409 (Conflict) which means that the object cannot be created again.

When executing the POST data on the server will likely change and therefor this operation is not 'safe'.  The post is no 'idempotent' operation because when you execute the POST multiple times the response results after the first request will not be the same as the first response result.

In the above example both the ID of the Customer as the ID of the Car are send with the request body. One other option is to use the navigation relation between Customer/Rental/Car to POST the new rental. This is shown in the picture below.

 

 

In this example you can see that the uri is different from the first example. Here the customer found by requesting through the customers resource using the ID of the customer as URI part. This way of navigation can be useful when the client for example has a list of Customers. When you click on a customer you can choose a Car and select the car for rental. Navigation to the customer was already setup using the URI so the request object can be sent without a CustomerID.

If the data send to the server in the request is invalid the server may respond with the HTTP Status Code 400 (Bad Request). The client then know that is should change the request body before sending it again.

Querying one ore multiple objects (GET)

When a POST is performed the location of the new created object is returned in the response. To get the information from the URI the URI must be requested with the GET verb. The GET verb can also be use the request a list of objects. If a GET is successful it will return a HTTP Status Code 200 (OK). In the response the requested object or list of objects is returned.

 

 

As you can see in this example the GET is executed on the location that was returned by the POST operation before. The body of the response contains the information as posted before. If the object requested does not exists the server will respond with a HTTP Status Code 404 (Not Found). The client will then know that is must create the object before requesting it.

In the URI above you can see that one rental object is requested with the id 'a4f5s2f'. But what if you want to display a list of all the cars that can be rent. For getting lists with objects the GET verb is also used but without the ID part of the URI.

 

 

The body of a GET from a single item of a GET with a list of item differ because the GET on a list of items will return an array of objects instead of one object.

The GET operation should be a 'safe' operation and cannot change data on the server. If you request the GET uri multiple times the result will be the same every time you request again therefor the GET operation is a 'idempotent' operation.

Updating an object (PUT)

If you want to update a resource the PUT verb should be used. The PUT is mostly used with an URI that contains an identifier so the server knows which object it should change. In the request body of the PUT the complete object is send to the server and the server will overwrite the data with this new information. If the update is successful the server will respond with the HTTP Status Code 200 (OK). This is the same as responded by the GET verb. Like with the POST operation if the data sent using the PUT verb is not valid the server will respond with the HTTP Status Code 400 (Bad Request).

 

 

As you can see in the example above the same URI is used as with the GET request. The body of the response contains the same information as the body of the request because if the update was successful the data is changed. If the data was already changed on the server it may respond with a HTTP Status Code 409 (Conflict). In some scenario's the server may respond with HTTP Status Code 204 (No Content) instead of the HTTP Status Code 200 (OK). This is mostly done because of minimizing data traffic between server and client. With the 204 the server presumes that the client will hold the objects after adding them to the PUT request.

If the server cannot find the object requested it will respond with a HTTP Status Code 404 (Not Found).

What about creating objects with a PUT? PUT can be used to create objects also and if that's the case then the server will not respond with a 404 (Not Found) but with a HTTP Status Code 201 (Created). So when to use PUT and when to use POST if both can create objects? The answer is fairly simple: If the id's are in control of the server POST should be used for creating objects. If the id's can be decided by the client PUT can also be used for creating objects.

The PUT is not 'safe' and but is 'idempotent'

Deleting objects (DELETE)

When objects are no longer needed the client can request a deletion of the object. The deletion is performed with a DELETE verb. The URI used for the DELETE operation is the same as the URI for the GET and/or PUT. If the object is deleted successfully the server will respond with a HTTP Status Code 204 (No Content).

 

 

It is also possible for the server to respond with HTTP Status Code 200 (OK) if the body contains the deleted object. This can be useful when implementing some sort of undo mechanism. On other (success) response  can be HTTP Status Code 202 (Accepted), this is used when the server accepts the delete but the object is not deleted yet.

The DELETE operation is not a 'safe' operation but can be implemented as 'idempotent' operation. If a object that the client is trying to delete is already deleted the server may response with the HTTP Status Code 200 (OK). This indicates that the delete is executed even if the object was not there. In this scenario it does not matter if you execute the delete multiple times the result will be the same and therefor the operation is 'idempotent'. If the server returns a HTTP Status Code 404 (Not Found) on deletion of a not existing object the operation is not 'idempotent' because executing the operation multiple times will then result in a 200 the first time and 404 every next attempt.

It's up the the designer of the API how this works, I personally prefer the 'idempotent' version of the DELETE operation. 

 

That's enough for today!

 

Other post(s) in this serie for know are:

The REST you know!! Or not? Part 1

Why this POST if you already know REST?

I have noticed that there are many different opinions about what REST is and how you can use to create an API that is easy to use. Sometimes REST API's are complex just because they are not created using correct REST. 

As a serious developer I don't want to write 'Bad Code' and hopefully I am not the only one! If you are planning to use REST and don't want to write 'Bad Code' either read this article. If you don't mind to write 'Bad Code' also read this article because you then know how to create 'Bad Code' by not implementing the solutions below ;-).

 

What is REST?

Let's begin with the basics. REST stands for Representational State Transfer (see WIKI - REST). Okay... So now you know, right? In short, REST is a communication protocol between client and server that is stateless. This means that the server does not keep track of the state between two requests. The communication can be cached for performance reasons. In most cases HTTP(S) will be used for communicating REST.

How does the communication work?

REST uses the HTTP verbs GET / POST / PUT / DELETE in most of the cases. Other Verbs can be used but in this article I will focus on these 4 verbs.

A lot of blogs and articles write about the REST verbs as a CRUD pattern with the following assumptions:

  • POSTCREATE (Insert)
  • GETREAD
  • PUT = UPDATE
  • DELETEDELETE

The above assumption is partially correct but you are not limited to this assumption. A PUT can also be used for the CREATE. This will be show in the PUT chapter below.

How do you think?

When you know other communication protocols between client and server you may have noticed that a lot of protocols are RPC (Remote procedure call) based. Which means that the client will request some operation from the server which will than result the output of the operation. REST is not RPC based but RESOURCE based, which means that your thinking pattern must change from RPC style (GetCars, RentCar) to RESOURCE based style (GET /cars, POST /rentals). Let's take a look how this really works. When you are implementing a REST API try to use Nouns and not to use Verbs for your URI's.

Domain model

When defining a REST interface the domain model for the rest interface must be clear. During a project changes will always occur, but some kind of domain model must be available to be able to define your model for the REST interface. 

The model I will use in my examples is about renting cars:

The model consists of 3 classes:

  • Customer which is the person that rents a car
  • Address which is an address of the customer 
  • Rental which is the resource for holding the rental period and link the Customer to a Car.
  • Car which is a car that can be rent.

When defining resources you have to identify the root aggregates of the model. For my model I see 3 root aggregate Customer, Rental, Car. From the application perspective these objects are likely to get their own screen with a list of object. All customers in the system, all Rentals in the system, all Cars in the system. Address is not a root aggregate because we will never lookup an Address on its own. Address will always be displayed for a Customer.

By identifying the root aggregates the following URI structure is appropriate:

/customers
/customers/{id}/addresses/
/rentals
/cars

One other resource can be the resource to show rentals for a customer:

/customers/{id}/rentals

 

In the next post(s) I will be talking about the different HTTP Verbs in detail, different Response Results, Security issues, Maturity model and lots of other topic about REST.

 

Other post(s) in this serie for know are: