Rest uri design for changing the status for resource

Suresh picture Suresh · Aug 14, 2013 · Viewed 12.9k times · Source

I have a resource that can be reach at the URI /resources/{resource_identifier} and it has a 'status' property that I want be accessible. I've thought of a few options for this, which would be the 'best' or 'most RESTfull'?

Option One Append actions onto the URI and have the client POST to these URIs

/resources/{resource_identifier}/void    
/resources/{resource_identifier}/open    
/resources/{resource_identifier}/close

This looks clumsy though.


Option Two Use a query param in the URI and have the client PATCH to these

/resources/{resource_identifier}?transition=void
/resources/{resource_identifier}?transition=open
/resources/{resource_identifier}?transition=close

Option Three Use the payload of the request and have the client PUT

/resources/{resource_identifier}

payload options:

{ ..., "status" :"void" }
{ ..., "status" :"open" }
{ ..., "status" :"close" }

Or maybe something else altogether?

Answer

thecoshman picture thecoshman · Jul 20, 2015

The first option is clearly not REST; you have 'actions' in the URI and are using POST, which is to create a new resource, which you clearly not attempting to do.

Looking at just the URI format for now. Option two is getting better, but query strings of that nature are more for reading data. Nothing really stops you doing it in this way. Option three has the best URI format, it is only referencing what resource you want to refer to in your request.

If we now consider the method of the request. In my book, this is rather simple, I presume that the status is only one field of this resource, and so if you are only doing a partial update, you are patching the resource, and thus PATCH is the method to use. On the off chance the 'status' is the only property, then changing the status is completely changing the resource and thus PUT would be acceptable; but I doubt that really is the case.

As it stands, the URIs of the third option, combined with use of PATCH is probably the best option.

PATCH /resources/{resource_identifier}

{ "status" :"close" }

Of course, you could also combine this with the concept of exposing specific attributes via their own URI as if they were a resource in their own right. Frankly, I don't like this, as it feels rather odd and only works for one attribute at a time. Still, if this is what you wanted to use, you could have something like:

PUT /resources/{resource_identifier}/status

close

Keep in mind, there is no "right" way of doing REST, just "not bad" ways. It's a style, not a rule set.

I also suggest you consider that being able to take many formats is a desirable feature, generally speaking. As such, the first option tends to be easier to work with. You could take JSON, as the example has, or swap it to XML <status>close</ status>, or a simple key value pair status=closed etc.