Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have two resources: users and links.

Users can have several links associated with them. I have designed my RESTful API so that you can reach the links associated with a user at the following URI:

/users/:id/links

However, I always need to have a URI for just links – sometimes I might want all links, regardless of user.

For this I have:

/links

Does this sound okay? Having two URIs for links?

I wonder if I should instead reach the links for a user with a URI such as:

/links/user/:id or /links/?user=:id

This way, I only have one resource for links.

share|improve this question
3  
hmm.. This one seems more elegant: /links/user/:id –  theMarceloR Feb 18 '13 at 20:16
4  
@theMarceloR: That's the only example out of the three that I don't find particularly clear. Is the resource for a link or a user? The URI is far less ambiguous using either the nested resource method (/users/:id/links) or the query string method (/links/?user=:id) since it is in fact a query. /links/user/:id might look nice and/or be easier to route in some frameworks but it is actually quite confusing. –  Aaronaught Feb 19 '13 at 0:06
add comment

1 Answer

up vote 4 down vote accepted

No, there is nothing wrong with having multiple resources for the same "thing", in this case lists of links.

We were recently struggling with the same problem. Our decision was to have all resources where there is not a strict ownership not to be nested. In other words, the links would be modeled under

/links -- all links
/links/:linkid -- a particular link

Then, filters on the links collection are expressed as query parameters. So to get the links of a certain user, you would use:

/links?user=/users/:userid

This also allows for easier composition of filters:

/links?user=/users/10&since=2013-01-01

And it is easy to understand conceptually - you have a collection of items, and you add filters to it.

That being said, there is nothing more "RESTful" about this approach than any other URI naming scheme. It's just a convention we found human-readable and easy for us developers to understand and embrace. REST doesn't care about what you put in your resource identifiers.

share|improve this answer
    
"All resources where there is not a strict ownership not to be nested" sounds like a good rule to have. Thanks a bunch. –  Oliver Joseph Ash Feb 18 '13 at 21:29
2  
I'd say that there is something wrong with having multiple resources for the same physical entity, but that's not actually what this is. Each individual link has a canonical URL (links/:id), whereas each of the resources above are in fact a single resource (/links) with filters applied. Also, I'm weirded out by the ?user=users/:userid in the query string; what is wrong with just ?userid=:userid? –  Aaronaught Feb 19 '13 at 0:03
    
@Aaronaught: the reason to stick to uri's instead of bare ids is so that clients can treat all resource identifiers equally, that is a client need only know that 'this user is identified by "/*******"; where the *'s are opaque. but that same identifier can always be used to refer to that resource (as in, with links), to fetch the most current version of that resource, and so on. the content of that uri is only understood by the origin server. This also means that if the identifiers need to change, say /realm/:businessid/users/:id, the client doens't change at all. –  TokenMacGuy Oct 19 '13 at 18:26
    
@TokenMacGuy: Sorry, I don't understand any part of your comment. What's the practical difference between /users/:userid/links and /links?userid=:userid? In both cases the identifiers don't change, they fetch the current version of that resource, and the client treats them the same way. There's no such thing as a canonical URL for this because it's not a resource, it's a query, so these are just two different types of query syntax. I'm also not clear on how the client wouldn't need to change if the URL structure changes; that's considered a breaking change in REST unless a 301 is in place. –  Aaronaught Oct 19 '13 at 19:52
    
@Aaronaught: I might have misunderstood your concern. Supposing /links supports a query interface, /links?user=/users/123 permits a black-box approach to resource identifiers in clients that /links?userid=123 does not. the latter requires the client understand what a userid is and how to get it, presumably out of the resource it obtained from /users/123 or /links/456/user. The former means the client can use the uri unmodified; supposing the /links/.../user gives a hypermedia response (say, with Location: headers). –  TokenMacGuy Oct 19 '13 at 22:00
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.