You are right in pointing out that there is nothing in the HTTP protocol that would provide an idempotent attribute of methods / verbs like PUT and DELETE . HTTP, a stateless protocol , does not store any information or status for every request that a user makes; Each individual request is considered independent.
To quote Wikipedia about the idempotent attribute of HTTP methods (emphasis added):
Please note that if the isempotent method does not apply the protocol or the web server. You can write a website application in which (for example) inserting a database or other non-idempotent action is triggered by GET or another request . ignoring this recommendation, however, can lead to undesirable consequences if the user agent assumes that repeating the same request is safe when it is not.
So, you can abandon the usual implementation and implement such things as a fixed POST implementation, a non-idempotent PUT, etc., probably without any significant, life-threatening technical problems. But you can risk breaking other programmers who consume your web services by thinking that you do not know what you are doing.
Here's an important quote from RFC2616 on HTTP methods safely (highlighted by me):
Developers should be aware that the software represents the user in their interactions over the Internet and should be careful that the user is aware of any actions they may take that may have unexpected implications for themselves or others.
In particular, it was agreed that GET and HEAD Methods SHOULD NOT have the value of taking action other than searching. These methods should be considered "safe." This allows user agents to present other methods, such as POST, PUT, and DELETE, in a special way so that the user is aware . the fact that a possibly unsafe action is being requested.
Naturally, it is impossible to guarantee that the server does not generate side effects as a result of executing a GET request; in fact, some dynamic resources believe that a function. An important difference is that the user did not request side effects, therefore, therefore, they cannot be held responsible for them.
UPDATE As indicated by Julian , RFC 2616 has been replaced by RFC 7231. Here is the relevant section .
So when you publish a web service as a PUT method, and I submit a request that looks like this:
PUT /users/<new_id> HTTP/1.1 Host: example.com
I expect a new user resource to be created. Similarly, if my request looks like this:
PUT /users/<existing_id> HTTP/1.1 Host: example.com
I expect the corresponding existing user to be updated. If I repeat the same request by submitting the form several times, do not open the warning dialog box (because I like the established agreement).
Conversely, as a consumer of the POST web service, I will expect requests such as:
POST /users/<existing_id> HTTP/1.1 Host: example.com
to update the corresponding existing user, while the query is as follows:
POST /users/<new_id> HTTP/1.1 Host: example.com
to raise an error because the URL does not exist yet.