My data model is like this:
User: id, email, hashed_password Item: id, name, color UserItem: user_id, item_id, rating and I want to write a RESTful API to get these resources. The authentication is provided via OAuth 2 with a JWT token (that contains the logged user id).
First approach
Endpoints
The first idea for a URL structure is (the one I chose when there was still no authentication):
/items/{item_id} /users/{user_id} /users/{user_id}/items/{item_id} In this case a user with id 1 could use:
GET /users/1to get their own information;GET /users/1/itemsto get their own items (with rating);GET /itemsto get all items that they could add to their collection.
Analysis
I think this solution is quite clear, but also unelegant.
Good:
- You can easily get other users info (if they are available to them);
- 1-to-1 relations between endpoints and data models.
Bad:
- Longer URLs;
- There is redundancy (why
GET /users/1/itemswhen in the token you already have the information about id 1?).
Second approach
Endpoints
Given that you can extract the user id from the token, the structure could as well be more simple:
/items/{item_id} /users/{user_id} In this case a user with id 1 could use:
GET /users/meto get their own information;GET /items?class=ownedto get their own items (with rating);GET /items?class=allto get all items that they could add to their collection.
Analysis
This solution is a bit messy but probably more elegant.
Good:
- Shorter URLs;
- Less redundancy (
GET /itemsto get your own items).
Bad:
- Only model UserItem is represented (even though in this case it is probably almost meaningless to get an Item without its rating, that could be set to null if the user has not yet added it);
- Not straightforward to get other users' items (maybe something like
GET /items?user=3?).
Conclusions
Honestly I don't know what is the best practice in this case. I feel like there is something off about both of these. Maybe there is an hybrid approach I'm not seeing?
How would you organize a model like this?