REST verb for state change - can we agree on POST?
The reference implementation of REST is the World Wide Web, which was catastrophically successful even though HTML (the dominant media type) only specified support for GET
and POST
.
Using POST
for unsafe operations is fine.
Although start looks like a verb (breaking REST-practices)
No -- REST doesn't care about the spellings of URI. That's part of the point: the server can change the URI in links any time it likes because the clients just follow the links.
That said, there is an issue with your proposed identifiers, which you may want to consider
/coffeemachines/{id}
/coffeemachines/{id}/start
As far as REST is concerned, these are different resources. That means that your locally cached copy of /coffeemachines/{id}
is not invalidated when you POST
a request to /coffeemachines/{id}/start
.
If you care to take advantage of the caching support that is already built into the domain agnostic components that are available, then you want the target of the POST
to match the target of the GET
: /coffeemachines/{id}
/coffeemachines/{id}/start
, in this design, isn't the target of the POST
, but is instead the identifier of the form resource that submits start messages to /coffeemachines/{id}
. Likewise, /coffeemachines/{id}/stop
would identify the form resource that submits stop messages.
The representation of the coffee machine would include links to these forms when the transitions are permitted; for instance, when the coffee machine is off, then the representation of the coffee machine returned by GET
would include a link to the start form, but not a link to the stop form.
/coffeemachines/{id}/start
and /coffeemachines/{id}/stop
are different resources from /coffeemachines/{id}
, and therefore might have their own caching policies.
Of course, it isn't required that the forms be separate resources -- the mechanism would also work if the forms were part of the representation of the /coffeemachines/{id}
resource itself.
Can I ask you to elaborate around POST vs PATCH
I found that this observation by Roy Fielding helped me:
HTTP does not attempt to require the results of a GET to be safe. What it does is require that the semantics of the operation be safe, and therefore it is a fault of the implementation, not the interface or the user of that interface, if anything happens as a result that causes loss of property
PATCH has stricter semantics than POST; that means that clients (and generic components) can make stronger assumptions about what is going on.
So in the following examples:
PATCH /foo HTTP/1.1
Content-Type: application/json-patch+json
POST /foo HTTP/1.1
Content-Type: application/json-patch+json
The server can handle these messages in exactly the same way. Clients that recognize the PATCH method will recognize that the unsafe changes on the server are supposed to be all-or-nothing ("The server MUST apply the entire set of changes atomically...") and can leverage that as they like, but with POST, that additional constraint is missing and cannot be assumed.
The PATCH spec notes:
A comparison to POST is even more difficult, because POST is used in widely varying ways and can encompass PUT and PATCH-like operations if the server chooses. If the operation does not modify the resource identified by the Request-URI in a predictable way, POST should be considered instead of PATCH or PUT.