Reputation: 302
I have a good resource hierarchy set up in my REST server, but I have one use case that is confusing me.
We have a fairly typical project/group setup, and referencing all of the groups in a project is easy enough. Sometimes, though, I want all groups with a given status (across all projects). This is clearly not possible in a standard subresource hierarchy.
The only clean solution I see is to have groups as a resource and a subresource (as they are addressable with a unique key) at the same time. I've thought about this notion of "aliasing" a resource before (addressing the same resource in two different ways), but I'm not sure of the best way to express that.
Upvotes: 0
Views: 918
Reputation: 14559
If you want your application to be scale-agnostic, it's best to think of your fundamental resources as uniquely-identified entities (see Helland) but allow for indices on them to be exposed. The most common form of index is a collection that contains its items, using the hierarchical nature of HTTP URI's:
GET /groups/
200 OK
{"entities": [
"/groups/1/",
...
"/groups/212/",
],
}
We might call that the "primary index". But there are many other possibilities:
GET /projects/foo/groups/
200 OK
{"entities": [
"/groups/7/",
"/groups/182/",
],
}
GET /groups/by_status/ACTIVE/
200 OK
{"entities": [
"/groups/13/",
"/groups/64/",
],
}
Be careful with these alternate indices, however, as they tend to get out of sync with reality, especially when you throw multiple servers and caches into the mix (read Helland's paper). This is why the example output above consists of links, not copies of the atomic entities themselves. For the same reason, you do not want to have two URI's which identify the same atomic entity. That will lead to stale data and lost updates as multiple clients obtain multiple copies of the same data.
If an entity is truly identifiable by two distinct identifiers, such as a numeric id and a unique name, then pick one to be canonical and have the other redirect to it:
GET /groups/by_name/bar/
303 See Other
Location: /groups/44/
Upvotes: 1