Reputation: 4589
We have a design where a user has access to products, but only in a certain category.
A superuser can list all products in all categories with a simple GET request, such as GET /products
.
Simple filtering already exists via the query string, so the superuser can already restrict his search to category N by requesting GET /products?category=N
.
Say that user X
is authenticated, and user X
has access to products with category of 3
.
Should an API server:
GET /products?filter=3
, and GET /products
would fail with 403 Forbidden
? -- orGET /products
and silently filter the results to those that the user is authorized to access?Upvotes: 3
Views: 656
Reputation: 57327
expect a simple GET /products and silently filter the results to those that the user is authorized to access?
Changing the representation of a resource depending on which user is looking at it strikes me was a Bad Idea [tm].
Consider, for instance, the use case where a uri gets shared between two users. They each navigate to the "same" resource, but get back representations of two different entites.
Remember - here's what Fielding had to say about resources
The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.
Now, there are conceptual mappings which depend on the perspective of the user (e.g. "today's weather in my city"). But I'm a lot more comfortable addressing those by delegating the work to another resource (Moved Temporarily to "today's weather in Camelot") than I am in treating the authorization credentials as a hidden part of the resource identifier.
If consumers of your api are arriving at this resource by following a link, then 403 Forbidden
on the unfiltered spelling is fine. On the other hand, if consumers are supposed to be bookmarking this URI, then implementing it as a redirecting dispatcher may make more sense.
The redirecting approach is consistent with remarks made by Fielding in a conversation about content negotiation on the rest-discuss list in 2006
In general, I avoid content negotiation without redirects like the plague because of its effect on caching.
E.g., if you follow a link to
then the site will redirect according to the user's preference to one of
Upvotes: 1
Reputation: 26137
Both of the solutions are perfectly valid. You can always hide things when the user does not have the permission to see them. This means, that you can display a filtered representation of /products
by the actual user, or you can hide the /products
resource and give link only to the /products?filter=3
resource. I don't think there is a best practice here, since both solutions are easy to implement.
@VoiceOfUnreason:
Apparently you did not read Fielding's work carefully enough.
Changing the representation of a resource depending on which user is looking at it strikes me was a Bad Idea [tm].
The representation depends on the whole request, not just on the GET /resource
part. The Authorization
header is part of the HTTP request as well. So changing the representation depending on the Authorization
header is valid in REST. It is just the same as changing the representation depending on the Accept
header. Or do you say that we should serve XML even if somebody requests for JSON? It is a huge mistake to think that a single resource can have only a single representation. Another mistake to return a broken link to the client and let them waste resources by sending pointless HTTP messages...
Consider, for instance, the use case where a uri gets shared between two users. They each navigate to the "same" resource, but get back representations of two different entites.
REST is for machine to machine communication and not for human to machine communication! The browser is not a REST client. Or did you mean that a facebook bot will share the link with a google crawler? Such a nonsense...
Upvotes: 0