views:

67

answers:

2

I'm designing a hypermedia API, yes, a RESTful API, with the hypertext constraint.

Each user of the system will access the system using their own credentials, so every request we process is authenticated and authorized. Each user will typically have specific credentials so that they may have different permissione (e.g. none, read, read/write) on each collection.

We want the client to be primed with the one URI that it starts with, which would be perhaps an atom services document, or a hierarchy (draft atom hierarchy extensions) of atom collections.

My question is basically should users see different representations for the same URI, or should users be directed to different URIs based on their permissions?

For example: User A and User B have different permissions in the system. They log in with different credentials, to the same start URI. A successful response may be one of the following 2:

  1. 200 OK, and User A sees something different than user B on the same URI
  2. 302 (or other redirect) each user to e.g. /endpoint/userA (which they own)

The tradeoff between cacheability is of course minimal, since resources are cached only by the client and not by intermediaries, but there's a tradeoff for visibility too (URI contains (aythenticated) user ID). Finally there's the future possibility of allowing User A (or a super user) to see what User B sees.

I'm not asking what Twitter or Facebook do, I'm more interested in what REST practicioners have to say about this.

A: 

Option 1, replying with 200 is an acceptable REST response and is more user friendly than option 2.

The Google Data APIs provide a decent REST implementation on top of their user services, and they implement option 1. For example the Google Calendar Data API allows a user to query the person's own feed by performing a HTTP GET request on http://www.google.com/calendar/feeds/default/private/full.

Sanjay
Sorry, but I specifically asked not to see "so-called REST APIs", and even though GData APIs are better than most, their API documentation still lists a lot of URIs (like the one you mention).But anyhow, why do you think option 1 is more acceptable than option 2? Perhaps you could edit your answer to include a reason?
mogsie
+1  A: 

Personally I find this a really tough call to make and I think it depends a lot how much content would change. If the difference is the omission of a few extra details then I would probably treat it as a single resource that varies based on the user.

However, once the differences start to get more significant then I would look at creating different resources. I would still try and avoid creating resources that are specific to a particular user. Maybe for a particular resource you could create a set of subresources, with differing levels of content. e.g.

/Customer/123?accesslevel=low
/Customer/123?accesslevel=medium
/Customer/123?accesslevel=high

This method in combination with the 302 may be sufficient in some cases. For more complex cases you could use multiple query string parameters.

/Employee/123?SocialSecurityNo=yes&SalaryInfo=yes

I do not believe there is an easy answer to this question. I think the answer is similar to most tricky REST scenarios: your solution can be as creative as you want as long as you don't violate the constraints :-)

Darrel Miller
It's true that both are equally valid and can easily be done within the REST constraints. I guess the question should have included more of a "per-user resource" but that would have colored the responses: Some resources are really per-user: The home page (e.g. the home page of twitter or facebook) is pretty different from user to user, but each resource (e.g. a twitter or fb profile page) is pretty much the same.
mogsie
@mogsie Due to the social nature of sites like twitter and facebook, the concept of user is very much a first class resource. In those cases I believe that every home page should have its own resource. e.g. 'http://twitter.com/user/darrelmiller/home'
Darrel Miller
So if we applied this to an API, would you inject the URL /user/darrelmiller/home into the client? or would you inject all clients with the same /home resource and have /home always redirect to /user/darrelmiller/home after authentication?
mogsie
If the current page is unauthenticated then it would need a link to /home and if the current page is authenticated then I could deliver the direct URI. Does that make sense?
Darrel Miller
@Darrel, you wrote the following as a response to a different question: *The only problem with keeping the two URLs around is that as per the resolution of Issue 14 Range w3.org/2001/tag/issues.html#httpRange-14 there should only be one URL that returns a 200 for single resource. There can be multiple URIs for a resource, but the others should return a redirect if dereferenced.* Wouldn't all the /Customer/123?xxxxx=yyyyy URIs all be the same **resource**?
mogsie
Link to referenced question: http://stackoverflow.com/questions/3234560/how-to-deal-with-merged-objects-resources-in-a-web-app-and-in-a-restful-api/3239977#3239977
mogsie
@mogsie As soon as you mint new URLs for them, from the client's perspective they are new resources. How you handle that on the server is another issue. I find trying to create a concrete implementation of a "resource" on the server to be very limiting. The term is far too imprecise.
Darrel Miller