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: