Matteo Silvestro
Matteo Silvestro

Reputation: 518

RESTful API URL design with authentication

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:

Analysis

I think this solution is quite clear, but also unelegant.

Good:

Bad:

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:

Analysis

This solution is a bit messy but probably more elegant.

Good:

Bad:

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?

Upvotes: 0

Views: 262

Answers (1)

Evert
Evert

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

Related Questions