Reputation: 518
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).
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/1
to get their own information;GET /users/1/items
to get their own items (with rating);GET /items
to get all items that they could add to their collection.I think this solution is quite clear, but also unelegant.
Good:
Bad:
GET /users/1/items
when in the token you already have the information about id 1?).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/me
to get their own information;GET /items?class=owned
to get their own items (with rating);GET /items?class=all
to get all items that they could add to their collection.This solution is a bit messy but probably more elegant.
Good:
GET /items
to get your own items).Bad:
GET /items?user=3
?).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?
Upvotes: 0
Views: 262
Reputation: 99543
You could look into a format like HAL. HAL gives you a way to describe specific resources (items) and allows you to create multiple collections that point to those resources.
This means that individual items could be hosted at /items/xyz
, but items can be both part of the /user/a/items
and /items
collections.
I put a lot of work into a hypermedia client: https://github.com/badgateway/ketting . This is not just an ad though, there's alternatives but that approach of API design might we well-suited for you.
But regardless of the client you're using, systems like this can avoid the issue of retrieving the same item through multiple endpoints. A single item has a canonical url, and if the system is designed well you only have to retrieve an item once.
A collection is just a list of links to the resources (items) that belong to that collection. They point to the item, but don't 'contain it', just like a regular hyperlink.
Upvotes: 2