Reputation: 14581
I have users, and I have groups
GET /user/1 -> {id:1,name:"john"}
GET /user/2 -> {id:2,name:"sam"}
GET /group/1 -> {id:100,name:"myGroup"}
Obviously, group-to-user is a many-to-many relationship. Ignoring the storage implementation, I am trying to figure out the sanest way to represent it.
/user/1/group // lists the groups of which "john" is a member, e.g. [100]
/group/100/user // lists the users who are members of "myGroup", e.g. [1]
One? The other? Both of them?
To take it one step further, what if I allow sam to see john (but no one else), because they are both members of group 100? Conceptually, LinkedIn or Facebook similarly allow you to see info about someone once you are connected.
So if john (1) requests info about sam (2), should I do:
/user/2 // allows it, with some backend mechanism finding the memberships of sam and john, and then finding that they are in the same group?
OR
/group/1/member/2 // this is john saying, "I want to access user 2 who is a member of group 1 and so am I"
The second option makes the request explain why they should be together, and makes the logic far simpler. On the other hand, user 2 already is a resource at /user/2
, so the alternate route seems strange?
Upvotes: 0
Views: 92
Reputation: 5519
First, your collections should use a plural form such as:
/users
/groups
Representing your users and groups depends on your business, I would say that your "users" are first-class citizens, so it should be:
/users/{userId}/groups
That would return all groups for user identified by its userId
. Note that /users/{userId}
could return user's groups as well, but it is up to you.
The following URI would work as well, but then again, it depends on what you want to do:
/groups/{groupId}/users
To take it one step further, what if I allow sam to see john (but no one else), because they are both members of group 100? Conceptually, LinkedIn or Facebook similarly allow you to see info about someone once you are connected.
This could be implemented by some sort of Access Control Lists (ACLs). If user A can't see data of B because they are not friends, then querying /users/B
will return nothing. However, if C (who is friend with B) performs the same request on /users/B
, he will be able to see data of B.
So I would go for the first option.
Upvotes: 1
Reputation: 13672
I would consider making a separate resource, maybe groupMemberships, which holds the relationship. You can still have something like GET /users/1/groups to get the groups directly, if it was worth it to you.
GET /groupMemberships?user=1
GET /groupMemberships?group=100
{
"href": ".../groupMemberships/abc123"
"user": {
"href": "/users/1"
}
"group": {
"href": "/groups/100"
}
}
Upvotes: 0