should I use PUT method for update, if I also update a timestamp attribute

opensas picture opensas · Apr 16, 2011 · Viewed 17.3k times · Source

To be more precise:

According to rest style, it's generally assummed that POST, GET, PUT, and DELETE http methods should be used for CREATE, READ, UPDATE and DELETE (CRUD) operations.

In fact, if we stick to the http methods definition the thing might not be so clear

In this article it's explained that:

In a nutshell: use PUT if and only if you know both the URL where the resource will live, and the entirety of the contents of the resource. Otherwise, use POST.

Mainly because

PUT is a much more restrictive verb. It takes a complete resource and stores it at the given URL. If there was a resource there previously, it is replaced; if not, a new one is created. These properties support idempotence, which a naive create or update operation might not. I suspect this may be why PUT is defined the way it is; it's an idempotent operation which allows the client to send information to the server.

In my case I usually issue updates passing all the resource data, so I could use PUT for updates, but everytime I issue an update I save a LastUser and LastUpdate column, with the user id that made the modification and the time od the operation.

So i'd like to know your opinion, because strictly speaking those two columns are not part of the resource, but they do prevent the operation from being idempotent.

saludos

sas

Answer

Darrel Miller picture Darrel Miller · Apr 16, 2011

Ignoring the comment about the REST style mapping CRUD to the HTTP methods, this is an excellent question.

The answer to your question is, yes you are free to use PUT in this scenario even though there are some elements of the resource that are updated by the server in a non-idempotent manner. Unfortunately, the reasoning behind the answer is quite vague. The important thing, is to understand what was the intent of the client request. The client intended to completely replace the contents of resource with the values passed. The client is not responsible for the server doing other operations and therefore the semantics of the HTTP method are not violated.

This is the reasoning that is used to allow a server to update a page counter when you do a GET operation. The client didn't ask for an update therefore the GET is safe even though the server chose to make an update.

The whole, complete resource versus partial resource debate has finally been spelled out in an update to the HTTP spec

An origin server SHOULD reject any PUT request that contains a Content-Range header field, since it might be misinterpreted as partial content (or might be partial content that is being mistakenly PUT as a full representation). Partial content updates are possible by targeting a separately identified resource with state that overlaps a portion of the larger resource, or by using a different method that has been specifically defined for partial updates (for example, the PATCH method defined in [RFC5789]).

So, what we are supposed to do is now clear. What is not so clear is why there exists this constraint on only being allowed to send full responses. That question has been asked and IMHO remains unanswered in this thread on rest-discuss.