REST API Tutorial

  • REST
  • JSON
  • Dark Mode

Idempotent REST APIs

In the context of REST APIs, when making multiple identical requests has the same effect as making a single request – then that REST API is called idempotent.

When you design REST APIs, you must realize that API consumers can make mistakes. They can write client code in such a way that there can be duplicate requests as well. These duplicate requests may be unintentional as well as intentional some time (e.g. due to timeout or network issues). You have to design fault-tolerant APIs in such a way that duplicate requests do not leave the system unstable.

An idempotent HTTP method is an HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. It essentially means that the result of a successfully performed request is independent of the number of times it is executed. For example, in arithmetic, adding zero to a number is idempotent operation.

If you follow REST principles in designing API, you will have automatically idempotent REST APIs for GET, PUT, DELETE, HEAD, OPTIONS and TRACE HTTP methods. Only POST APIs will not be idempotent.

  1. POST is NOT idempotent.
  2. GET, PUT, DELETE, HEAD, OPTIONS and TRACE are idempotent.

Let’s analyze how above HTTP methods end up being idempotent – any why POST is not.

HTTP POST

Generally – not necessarily – POST APIs are used to create a new resource on server. So when you invoke the same POST request N times, you will have N new resources on the server. So, POST is not idempotent.

HTTP GET, HEAD, OPTIONS and TRACE

GET, HEAD, OPTIONS and TRACE methods NEVER change the resource state on server. They are purely for retrieving the resource representation or meta data at that point of time. So invoking multiple requests will not have any write operation on server, so GET, HEAD, OPTIONS and TRACE are idempotent.

HTTP PUT

Generally – not necessarily – PUT APIs are used to update the resource state. If you invoke a PUT API N times, the very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything. Hence, PUT is idempotent.

HTTP DELETE

When you invoke N similar DELETE requests, first request will delete the resource and response will be 200 (OK) or 204 (No Content). Other N-1 requests will return 404 (Not Found). Clearly, the response is different from first request, but there is no change of state for any resource on server side because original resource is already deleted. So, DELETE is idempotent.

Please keep in mind if some systems may have DELETE APIs like this:

DELETE /item/last

In the above case, calling operation N times will delete N resources – hence DELETE is not idempotent in this case. In this case, a good suggestion might be to change above API to POST – because POST is not idempotent.

POST /item/last

Now, this is closer to HTTP spec – hence more REST compliant.

References:

Rfc 2616
SO Thread

TwitterFacebookLinkedinReddit

13
Leave a Reply

This comment form is under antispam protection
4 Comment threads
9 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
11 Comment authors
This comment form is under antispam protection
  Subscribe  
newest oldest most voted
Notify of
FKorning

This is just plain wrong.

The problem is that there are naïve or overzealous interpretations of “idempotent”. Many think that since you’ve inserted a row, the system state has changed, therefore, this is not idempotent, therefore a create should be a POST.

This is wrong. HTTP is a stateless protocol; thus Idempotency in HTTP is contextual and refers to repeatability of the request. It means: if I call the same method again, will I get the exact same result (or am I at least trying to manipulate the same object) ?

So in our case, since all our entity objects are unique, If I try to create the same object, it should either allow it and overwrite the existing one, or throw an exception for object already exists (which is fine).

The only time one could use POST to create entities, is when they are not unique (no id), (or all ids are system-generated), such that a second POST ( /user/BOB ) would create two BOB users with separate generated userIds This is definitely not the case for most systems.

In our case, each entity type has at least one non-generated id with a unique constraint. For example, in a User, the login is meant to be unique. We expect the system to throw an exception if one attempts to a second users with same login “BOB”.

ergo, this is not a POST.

Vote Up0Vote Down  Reply
2 months ago
FKorning

TO clarify, if your entities provide non-generated unique ids:

CREATE = PUT
READ = GET
UPDATE = POST*
DELETE = DELETE
—-
find/list = GET
complex filtered find/list = POST
other complex operations = POST

*Most stay well-clear from the dreaded PATCH

Vote Up0Vote Down  Reply
2 months ago
Ju

PATCH is missing. It’s ike POST not idempotent since it’s usually used to partially update a resource (for example just sending and setting the first name of a user profile, ignoring the state of the remaining data).

AFAIK PUT can also create a new entity (but always the same, so calling it twice wouldn’t create two entities – basically you’re providing also the ID of the element to be created and if it already exists it’s being overwritten, but it doesn’t have to exist when using PUT the first time). Of course this depends on the implementation. But it would be valid.

Vote Up0Vote Down  Reply
9 months ago
Admin

Thanks for sharing your thoughts. It helps.

Vote Up0Vote Down  Reply
9 months ago
Pavan

When we send a POST request, it will create a new resource. Now if we resend identical POST request N times, conflict error would be returned as an identical record already exists. So, in this case will POST be idempotent (like the DELETE case you mentioned) as the resource on server remains same?

Vote Up0Vote Down  Reply
2 years ago
Hua Liang

I think you are more like a business/implementation side of question while this post is merely providing concept/theory of REST idempotence in general.

Vote Up0Vote Down  Reply
1 year ago
John

In a POST, the server determines the new ID, not the client, so that would be an improper implementation. PUT is appropriate for creation when the client is allowed to determine the new resource ID, so that scenario should use a PUT, which would be idempotent.

Vote Up0Vote Down  Reply
1 year ago
Andrzej Pienczykowski

It is a good practice to have a candidate keys that by definition are also unique. That would prevent creating duplicate resources. It is obviously not possible for all types of resources.

Vote Up0Vote Down  Reply
1 year ago
Orijit

Resending identical POST requests N times will create N resources, each with a new ID. In the case an ID is involved, PUT would update the document with the same ID N number of times and produce same result.

Vote Up0Vote Down  Reply
1 year ago
Tony Wallace

Wrong. A put is NOT the same as a create command in a database. It is more like writing out a file out of a text editor. If it does not exist, it creates the resource (return 201), it it does exist it updates it (return 200).

Vote Up0Vote Down  Reply
11 months ago
Mariot

Shouldn’t it be “POST /item/last/delete” ?

Vote Up0Vote Down  Reply
2 years ago
Yves De Muyter

Can you explain to me what resource is /item/last/delete ? It’s an URL so a resource, but I’m not sure what a “delete” resource is exactly…

Vote Up0Vote Down  Reply
3 months ago
Admin

Almost 2 yrs now. I have no recall why nodded to that.

Vote Up0Vote Down  Reply
3 months ago

Learn REST

  • What is REST?
  • REST Constraints
  • REST Resource Naming Guide

Guides

  • Caching
  • Compression
  • Content Negotiation
  • HATEOAS
  • Idempotence
  • Security Essentials
  • Versioning
  • Statelessness

Tech – How To

  • REST API Design Tutorial
  • Create REST APIs with JAX-RS 2.0

FAQs

  • PUT vs POST
  • N+1 Problem
  • ‘q’ Parameter

Resources

  • Comparing SOAP vs REST APIs
  • HTTP Methods
  • Richardson Maturity Model
  • HTTP Response Codes
    • 200 (OK)
    • 201 (Created)
    • 202 (Accepted)
    • 204 (No Content)

References

  • The dissertation by Roy Thomas Fielding
  • Uniform Resource Identifier (URI, URL, URN) [RFC 3986]
  • Internet MediaTypes
  • Web Application Description Language (WADL)

Meta Links

  • About
  • Contact Us
  • Privacy Policy

Blogs

  • How To Do In Java
Creative Commons License
This work by RESTfulAPI.net is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
wpDiscuz