Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idempotence of HTTP PUT and DELETE

So the HTTP spec says that HTTP PUT and DELETE should be idempotent. Meaning, multiple PUT requests to the same URL with the same body should not result in additional side-effects on the server. Same goes with multiple HTTP DELETEs, if 2 or more DELETE requests are sent to the same URL, the second (or third, etc) requests should not return an error indicating that the resource has already been deleted.

However, what about PUT requests to a URI after a DELETE has been processed? Should it return 404?

For example, consider the following requests are executed in this order:

  • POST /api/items - creates an item resource, returns HTTP 201 and URI /api/items/6
  • PUT /api/items/6 - updates the data associated with item #6
  • PUT /api/items/6 - has no side effects as long as request body is same as previous PUT
  • DELETE /api/items/6 - deletes item #6 and returns HTTP 202
  • DELETE /api/items/6 - has no side effects, and also returns HTTP 202
  • GET /api/items/6 - this will now return a 404
  • PUT /api/items/6 - WHAT SHOULD HAPPEN HERE? 404? 409? something else?

So, should PUT be consistent with get and return a 404, or like @CodeCaster suggests, would a 409 be more appropriate?

like image 961
danludwig Avatar asked Oct 29 '12 15:10

danludwig


People also ask

Is HTTP delete idempotent?

2.4 HTTP DELETE Clearly, the response is different from the first request, but there is no change of state for any resource on the server-side because the original resource is already deleted. So, DELETE is idempotent.

How is HTTP put idempotent?

An HTTP method is idempotent if an identical request can be made once or several times in a row with the same effect while leaving the server in the same state. In other words, an idempotent method should not have any side effects — unless those side effects are also idempotent.

Why are get put and delete idempotent?

GET, HEAD, OPTIONS and TRACE methods are defined as safe, meaning they are only intended for retrieving data. This makes them idempotent as well since multiple, identical requests will behave the same.

Is Put method is idempotent?

The difference between PUT and POST is that PUT is idempotent: calling it once or several times successively has the same effect (that is no side effect), whereas successive identical POST requests may have additional effects, akin to placing an order several times.


1 Answers

RFC 2616, section 9.6, PUT:

The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource.

And:

If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem.

So to define 'appropriate' is to look at the 400-series, indicating there's a client error. First I'll eliminate the irrelevant ones:

  • 400 Bad Request: The request could not be understood by the server due to malformed syntax.
  • 401 Unauthorized: The request requires user authentication.
  • 402 Payment Required: This code is reserved for future use.
  • 406 Not Acceptable: The resource identified by the request [...] not acceptable according to the accept headers sent in the request.
  • 407 Proxy Authentication Required: This code [...] indicates that the client must first authenticate itself with the proxy.
  • 408 Request Timeout: The client did not produce a request within the time that the server was prepared to wait.
  • 411 Length Required: The server refuses to accept the request without a defined Content- Length.

So, which ones may we use?

403 Forbidden

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated.

This description actually fits pretty well, altough it is usually used in a permissions-related context (as in: YOU may not ...).

404 Not Found

The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.

This one too, especially the last line.

405 Method Not Allowed

The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.

There are no valid methods we can respond with, since we don't want any method to be executed on this resource at the moment, so we cannot return a 405.

409 Conflict

Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.

But that assumes there already is a resource at the URI (how can there be a conflict with nothing?).

410 Gone

The requested resource is no longer available at the server and no forwarding address is known. This condition is expected to be considered permanent. Clients with link editing capabilities SHOULD delete references to the Request-URI after user approval. If the server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD be used instead.

This one also makes sense.


I've edited this post a few times now, it was accepted when it claimed "use 410 or 404", but now I think 403 might also be applicable, since the RFC doesn't state a 403 has to be permissions-related (but it seems to be implemented that way by popular web servers). I think I have eliminated all other 400-codes, but feel free to comment (before you downvote).

like image 169
CodeCaster Avatar answered Oct 24 '22 05:10

CodeCaster