Idempotent and Safe Methods of HTTP and REST

In this tutorial, I will be sharing what are idempotent and safe methods of HTTP and REST.
The recent trend in programming is Cloud computing. Cloud computing mostly depends on REST/SOAP based request/response. One service can communicate with other services through REST/SOAP API. REST/SOAP uses HTTP protocol to communicate between server and client.

Read Also: RESTful Web Services Beginners Tutorial

HTTP (Hypertext transfer protocol) is a stateless protocol to transfer data between client and server. Actually, HTTP methods contain either request or response messages. It can contain request/response header, payload or response status. HTTP has different verbs to communicate between the two systems. HTTP verbs are those HTTP methods by which two systems can identify what kind of task it should do. GET, PUT, HEAD, POST, DELETE, PATCH are some HTTP methods or HTTP verbs. Some of the methods are safe and some are not. All safe methods are idempotent method. But all idempotent methods are not safe. For example, the PUT method is not safe but idempotent.

What are Idempotent Methods?

For every successful HTTP request, its result will be independent of the number of times it is executed. In other words, if the same HTTP method is called many times with identical data should return the same result(or response) then we define this call as idempotent call. Like multiple GET requests only fetch data from the server. Even multiple successive calls with the same data will return the same response. For example,


int k = 20;

If we call a method that will return the value of k, it will return 20 every time. That’s why this is idempotent. No matter how many times you execute the above line but the response will always be the same.

int k++;

Now, if we call a method which will return k = k +1 result every time, then, the result will be different. This is not idempotent as the result keep changing with every new request. We will discuss safe HTTP methods later in the article.

Before we go deep about idempotent, you can understand about different HTTP methods/verbs here.

HTTP defines some request methods by which we can communicate with the server and the server can decide which type of action it will perform. These request methods are called HTTP verbs/methods.

Read Also: WebServices Interview Questions

We will proceed with further steps with an example. Here I am using the Spring Boot sample application. You can download the project from here. I have written a rest controller with some HTTP methods.


package com.javahungry.idempotent;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping(value = "hello")
public class TestController {

   static class User{
      Long id;
      String name;

      public Long getId() {
         return id;
      }

      public void setId(Long id) {
         this.id = id;
      }

      public String getName() {
         return name;
      }

      public void setName(String name) {
         this.name = name;
      }
   }

   public List<User> users = new ArrayList<>();

   @GetMapping
   public List<User>  getHelloStrings() {
      return users;
   }

   @PostMapping
   public String add(@RequestBody User user) {
      Long id = new Date().getTime();
      user.setId(id);
      users.add(user);
      return "Resource added with ID =  "+id +" And Name = "+user.getName();
   }

   @PutMapping("{id}")
   public String update(@PathVariable Long id, @RequestBody User user) {
      for (User u:users) {
         if(u.getId().longValue() == id.longValue()){
            u.setName(user.getName());
            return "Resource updated with ID =  "+id +" And Name = "+user.getName();
         }
      }
      return "Resource not found with provided information";
   }

   @DeleteMapping("{id}")
   public String delete(@PathVariable Long id) {

      for (User u:users) {
         if(u.getId().longValue() == id.longValue()){
            users.remove(u);
            return "Resource removed with ID "+ id;
         }
      }
      return "Resource not found with provided information";
   }

   @PatchMapping("{id}")
   public String patch(@PathVariable Long id, @RequestBody User user) {
      for (User u:users) {
         if(u.getId().longValue() == id.longValue()){
            u.setName(user.getName());
            return "Resource updated with ID =  "+id +" And Name = "+user.getName();
         }
      }
      return "Resource not found with provided information";
   }
}

We will run the application using mvn spring-boot:run. After the completion of deployment, we will follow the below steps.

We will make a POST request using curl from our terminal.

curl -X POST -H "Content-Type: application/json" -d '{"name":"Javahungry"}' http://localhost:8080/hello 

It is a POST request. It will return a message after creating task completion. After this POST request, the server will send the below response.

Resource added with ID =  1583646602473 And Name = Javahungry

We can make many requests with the same request body, it will create a new resource every time on DB. So, the POST method is not idempotent.

Now, we will make a curl request to get saved data. In other words, GET request example

curl http://localhost:8080/hello

We should get a response like this:

[{"id":1583646602473,"name":"Javahungry"}]

If we make many GET requests, again and again, the server will return the same response. That means the response is not changed with the GET request. This call will not change any data on the database. We can call the GET method as idempotent.

Now we can test the PUT method. We will execute the following command. Method body will contain JSON format data and the last part of the request URL will contain the id of data that we want to update.

curl -X PUT -H "Content-Type: application/json" -d '{"name":"Javahungry Updated"}' http://localhost:8080/hello/1583646602473

If we execute PUT curl command it will return below output:

Resource updated with ID =  1583646602473 And Name = Javahungry Updated

If we again execute GET command it will now provide below output:

[{"id":1583646602473,"name":"Javahungry Updated"}]

PUT request will update the data related to the provided ID in request URL. If we make many requests with the PUT method, it will just update the same resource that is related to the provided id. It will not create another resource. That’s why PUT is idempotent.

DELETE request as the name suggests will delete the resource.

curl -X DELETE  http://localhost:8080/hello/1583646602473

DELETE method will remove the object related to the provided id. Multiple calls with the same id will not found resources. Multiple delete request with identical data will not change the database or response. That’s why the DELETE method is also idempotent.

We can summarize for most used HTTP methods/verbs like this:

POST, PATCH are NOT idempotent
GET, PUT, DELETE, HEAD  are idempotent

What are the Safe Http methods/verbs?

HTTP methods that do not change or update the resource in the server are called safe methods. Like GET or HEAD call never changes the resource in the server or database thus those methods are safe methods. On the above example, if you make many GET method calls you can see that every time it will return the same data without adding/updating any resource. Like GET method HEAD or OPTION, methods are also not updating/creating any resource in the server. That’s why these methods are safe. But the POST method will create a resource in every request and the PUT/PATCH method will update any resource in the server. That’s why those methods are not safe.

Idempotent and Safe methods of HTTP and REST

Conclusion:

The idempotent method does not change the response. Multiple requests do not make any effect on response. So, those methods are called the idempotent method. The safe method will not change/update resources on the server.

That's all for today, please mention in comments in case you have any questions related to what are idempotent and safe methods of HTTP and REST.

Download Source Code:

Download – Idempotent.zip

About The Author

Subham Mittal has worked in Oracle for 3 years.
Enjoyed this post? Never miss out on future posts by subscribing JavaHungry