ByteByteGoHq/system-design-101

REST design comments

icebob opened this issue · 5 comments

icebob commented

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.
image

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.
image
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.

icebob commented

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}
icebob commented

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.

macie commented

@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?.