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?
Constructing a Standard URIAvoid using spaces − Use underscore (_) or hyphen (-) when using a long resource name. For example, use authorized_users instead of authorized%20users. Use lowercase letters − Although URI is case-insensitive, it is a good practice to keep the url in lower case letters only.
In cases where URIs must change (e.g., when merging two applications, major redesign, etc.), honor old URIs and issue redirects to clients with the new URI using 301 ( Moved Permanently ) responses or, in rare cases, by issuing a 410 ( Gone ) for URIs that are no longer valid.
However, every character within a URI counts toward a resource's unique identity. Two different URIs map to two different resources. If the URIs differ, then so do the resources, and vice versa.
URI. REST APIs use Uniform Resource Identifiers (URIs) to address resources. REST API designers should create URIs that convey a REST API's resource model to the potential clients of the API. When resources are named well, an API is intuitive and easy to use.
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.
Why not have 'status' as resource. You can manage it. Also assume that there should be already a 'status' created as part of the {resource_identifier}
resource creation and there is already a default value for the status.
Then the business logic need is just to 'update' the status via the rest call and therefore 'PUT' should be used.
updated Moving status to the Put-Body
PUT: /resources/{resource_identifier}/status/
Body: {void | open | close }
Your second option looks better because you're maintaining the RESTful url structure and not appending RPC-style methods to the end of it.
Why not just do this:
PUT
to /resources/:id
and send the data transition=void
with the request.
It behaves in the same way it would if you were receiving a POST request, just grab the data out of the request body.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With