6

Having to create a RESTful web service with admin and normal user access to resources (lets say cars), I would like to structure the Uri for the users as:

http://myhost/users/5/cars/2

But as admin user, I would like to access all cars like:

http://myhost/cars/51

Instead of the first I proposed, would you think that it's better to use just one Uri for cars, using filters for users, like:

http://myhost/cars/?user=5

To don't have 2 different Uris for the same resource? Do you have other suggestions?

Patrizio Rullo
  • 491
  • 1
  • 4
  • 13

2 Answers2

12

Both of the following URLs are good, even for admin even for plain users. Auth-token should be in the HTTP session, so the server should be able to detect if the requester is admin or not.

http://myhost/cars returns a collection of cars. It's recommended that returned cars are filtered based on authorization. If I'm an admin I can see all cars. If I'm user #5 then probably I can see only my car. So both admin and plain user can use the same URL.

In the case of http://myhost/cars/?user=5 an explicit filter is applied where I'm interested in car for User #5 even if I'm somebody else. Probably I get an empty list because I'm not authorized to see any item. This URL is also OK.

http://myhost/cars/51 means that I want to access car #51 directly. Doesn't matter if I'm admin or not. Probably I'll get a 4XX message (what is XX is another debate) if I'm not authorized to see this entity.

pcjuzer
  • 2,724
  • 4
  • 25
  • 34
  • Thank you for the very detailed and clear explanation! I'll follow your advice for sure! – Patrizio Rullo Sep 16 '16 at 14:37
  • i would ask about this, how I could separate the query to database between admin and users, do I make two controller to do that ?? – monti Apr 28 '21 at 03:17
  • It's possible with only one controller. Assemble the DB query dynamically based on the caller user's permission situation. In SQL: add extra 'where' clauses to the DB queries when some filtering should be applied for the actual user. – pcjuzer Apr 28 '21 at 10:46
  • Our use Row Level Security in your database. Conditionally adding where clauses for all your API endpoints seems very error prone. – David Spiess Apr 08 '23 at 08:02
-2

The user identifier should not be a part of the uri as the user retrieving the resource has no relation to the resource being retrieved. When there is a parent child relation between the resources, you typically include them in the uri.

The user's access to the resource in your case should be deduced from the authorization token that they send with the request.

  • Indeed the user has to be deduced from the authorization token for security reasons, but in this case, there is also the relationship: User has many Cars. So in this case, you think that the Uri: http://myhost/users/5/cars/2 it's also not good? – Patrizio Rullo Jan 28 '16 at 20:22
  • Since the rest call should execute under the context of the user identity obtained from the authorization token, there is no need for the "user" in the uri. The uris can be simplified to `myhost/car/2` when you are getting a specific car (notice the singular for car). For a non admin user, you would check if they have access to / are related to that specific car and for an admin user, you would just give the car with out any relationship check. – Seshu Kumar Alluvada Jan 28 '16 at 22:04