REST design comments
icebob opened this issue · 5 comments
Hi,
I have some comments for the section on effective REST API design:
1. Use the same casing method
You use camel-case in most variable names except the sort_by
. It would be better as sortBy
to follow the conventions.
2. Skip the action from URL path
The "Idempotency" example shows a good path POSTS /carts
without any action name.
But the cart example URL contains the action name. It is unnecessary because the POST
method defines the action.
So I recommend changing it to
POST /carts/123/items
{ itemId: "321" }
By the way, nice collection, good job!
Yeah! I agree with you on both. I was reading this REST table and wondered if some asked about it.
So I want to get a little bit deeper. People say that http verbs (get, post, put, delete, etc) is all you need to perform an action and that paths should only contain resources (so nouns). Example here shows that path includes a verb :add
. While I think that this specific point can be a little confusing, my question isn't about convention, but have anybody seen using this pattern successfully? Like what's the reasoning? And if so why not POST /carts/123/items/add
? Going even further - how does it fit in hateoas picture?
I just started reading Roy Fielding dissertation on REST and I'm hoping to get some answers about REST.
The add
is the same as create
, but for creating a new entity, we don't write create in the path, just using POST
method.
This is why I use POST /carts/123/items
only.
However, I'm using the verb in the path if it's not a CRUD action and mutating a certain item, e.g increaseQuantity
:
POST /carts/123/items/321/increaseQuantity
But then why not
PUT /carts/123/items/321
{"quantity": <new quantity>}
or
PUT /carts/123/items/321
{"increaseBy": 1}
In CRUD methods, the PUT
is used to update an existing record (entirely) and the PATCH
is used to update an existing record (partly). POST
is the common mutation method.
Btw, currently, there is nothing any strong definition of the HTTP methods.
@macieyng REST is about having easy to remember interface. There are limited number of possible actions (HTTP method) which can be applied on arbitrary resource ID (URI) and they may respond with one of known number of error states (HTTP response status code).
So instead of
PUT /carts/123/items/321
{"quantity": <new quantity>}
you can do:
PUT /carts/123/items/321/quantity
<new_quantity>
This resource path don't need to be mapped 1:1 to database object, object in your language or filesystem path.
Path with verb is sign, that author has RPC mindset. API which mixes RPC with REST will be difficult to understand and error-prone ("is PUT /item/2/increase
idempotent?", "which error message strings can we safely ignore?").
HATEOAS is about API self-discovering - you should be able to learn possible actions from result only. JSON wasn't designed with that in mind, so now we spend time on Swagger and API exploration tools. See: How Did REST Come To Mean The Opposite of REST?.