When Is POSTing State Appropriate?
In an article, Tim Bray, examines the feedback from the first public draft of the APIs for the Sun Cloud. He responds to feedback in the article and explores the ways to model interactions such as, creating a VM in a Cluster, in a RESTful way.
He presents a few scenarios in the context of the design of Sun’s cloud API’s and asks if POSTing state to model such interactions is an appropriate strategy.
But you’re not really changing a state, you’re requesting a specific set of actions to happen, as a result of which the state may or may not attain the desired value. In fact, when you hit the
deployswitch, the state changes to
deployingand then after some unpredictable amount of time to
deployed. And the
rebootoperation is the classic case of a box with a big red switch on the side; the problem is how to push the switch.
So, the more I think of it, the more I think that these resources are like buttons, with only one defined operation: push. People have been whining about “write-only resources” but I don’t have a problem with that because it seems accurate. The
haltbuttons don’t really have any state, so you shouldn’t expect anything useful from a GET.
Bill de hÓra in reaction to the article provided, with examples, the distinction between PUT and POST and when one is more appropriate vs. the other.
When does PUT v POST actually *matter*? It matters, as far as I can tell, when your resource stands for a collection, which is very common - folders, albums, feeds, collections, blogs, tagclouds, orders, a shopping cart - any list based structure.
He also presents a more pragmatic aspect of the whole debate and suggests POSTing forms as a possible solution.
On the other hand lots and lots and lots of people don't, won't (and sometimes can't) care about REST/HTTP/AtomPub arcana. So some part of me thinks we need patterns and practices to help developers jfdi [just do it].
But as far it goes as I'm not sure we in the pro-REST community have a good general answer or design pattern for partially updating a resource. Until we do, I predict people will tend drop down to using forms posting as it's the easiest and most portable approach for deployed client libraries and web frameworks. That or define some other specialised media type for partial updates.
Roy Fielding responded to the article as well.
The main reason for my lack of specificity [in my thesis] is because the methods defined by HTTP are part of the Web’s architecture definition, not the REST architectural style. Specific method definitions […] simply don’t matter to the REST architectural style, so it is difficult to have a style discussion about them. The only thing REST requires of methods is that they be uniformly defined for all resources (i.e., so that intermediaries don’t have to know the resource type in order to understand the meaning of the request).
POST only becomes an issue when it is used in a situation for which some other method is ideally suited. The other methods are more valuable to intermediaries because they say something about how failures can be automatically handled and how intermediate caches can optimize their behavior. POST does not have those characteristics, but that doesn’t mean we can live without it. POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
Roy concludes his response saying
We don’t need to use PUT for every state change in HTTP. REST has never said that we should. […] Personally, I would just use POST for that button. The API can compensate for the use of POST by responding with the statement that the client should refresh its representation of the larger resource state. In other words, I would return a 303 response that redirected back to the VM status, so that the client would know that the state has changed.
The original article is available here with reactions from the community.
Going one level up in the question
That is, with no intention of using REST, the Post dilemma may simply not exist.
So, I think the issue may be seen through different glasses:
1. The actual suitability of Post to do a State change, or partial update as mentioned.
2. The actual suitability of using the web implementation semantics for such an application.
3. The actual suitability of REST style to implement that application.
See the point? In (1), we agree to use the regular HTTP operation semantics to create our application. Reading HTTP 1.1 Spec, the Post is to append, annotate or post info to a process for its processing. SO? The last option fits nicely, if you think of the application as a process waiting for data commands to be processed. Is that idea of a process a resource? (Read the REST dissertation).
Now, let say web is for distributed hypermedia. Do its semantics match the application semantics? Is the application a distributed hypermedia system? If not, we shouldn't force the application semantics to behave as a hypermedia distribution thing, because it is not.
Same for REST. REST is an architectural style that restricts the application architecture. And the architecture needs to fit the applications needs. If your application does not require the benefits of REST nor it fits its constrains, it is a non-sense to try tweaking the apps semantics simply because we want it to be RESTfull and thus going on with the hype.
The majority of answers in the posts are trying to find a way to map the functionality needed to resources and states and then trying to define which operation to use against it. So, we end up creating multistate button resources with temporary state changes and I don't know what other things in order to send a shutdown command! Please! That is wagging the dog!
William Martinez Pomares.
Re: Going one level up in the question
Its the asynchronous nature of such a request that I believe is the reason for the debate (also why it appears like a process to you perhaps). Would it change the problem, if the resource were truely a RESTful resource, Products for e.g. that had a latency associated with any changes to the state(unit price)?
One really good reason reason that someone would try to model it RESTfully is the simplicity, discoverability and the possibilities of serendipitous (re)use of the solution.
Re: Going one level up in the question
The problem still the same: A simply modeled solution not using REST becomes very complex if you need to change the app to fit the style.
Not sure about the debate, since it seems too many people solves the issue differently. The point is in the Post semantics. See:
1. REST talks about resources of which you obtain a representation that you can only work locally. There is a standard set of operations you can perform against such a resource, and that all the implementation is hidden in the server. Now, REST does not define the operations. By implementing REST using the web standards, URL, HTTP, you have then an application, the web, that defines that set of operations with HTTP.
2. The debate is, trying to use HTTP to implement a REST api it was not designed to handle, how can I map the operations to the problem I need to solve? Well, Roy follows a similar solution to the one you propose, but he still uses post.
Now, why do I need to affect the same resource I'm monitoring? And why do I think of State in the server or state of a resource, when the state should be stored, by REST, at the client, and it is the actual application state? See the confusion about states?
If the resource is the power controller, it is semantically incorrect thinking of modifying it. I would think of sending info to it (post) so it can process it. That may affect the representation of another resource (a machine), so the post sends me a 303 showing me the next step is to ask for that other resource's representation (which will contain the state).
Hope that helps understand my thinking.
William Martinez Pomares.
Camille Fournier May 21, 2015