当存在多对多关系时,我应该如何构建REST资源路径

时间:2013-08-13 12:02:17

标签: rest

我有用户,我有群组

GET /user/1 -> {id:1,name:"john"}
GET /user/2 -> {id:2,name:"sam"}
GET /group/1 -> {id:100,name:"myGroup"}

显然,群组与用户之间存在多对多关系。忽略存储实现,我试图找出代表它的最安全的方法。

/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]

一个?另一个?他们两个?

更进一步,如果我允许山姆看到约翰(但没有其他人),因为他们都是100组的成员怎么办?从概念上讲,LinkedIn或Facebook同样允许您在连接后查看有关某人的信息。

因此,如果john(1)请求有关sam(2)的信息,我应该这样做:

/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"

第二个选项使请求解释了它们应该在一起的原因,并使逻辑变得更加简单。另一方面,用户2已经 /user/2的资源,所以替代路线看起来很奇怪?

2 个答案:

答案 0 :(得分:1)

首先,您的馆藏应使用复数形式,例如:

/users
/groups

代表您的用户和群组取决于您的业务,我会说您的“用户”是一等公民,所以它应该是:

/users/{userId}/groups

这将返回由其userId标识的用户的所有组。请注意,/users/{userId}也可以返回用户的组,但这取决于您。

以下URI也可以使用,但是再次,它取决于您想要做什么:

/groups/{groupId}/users
  

更进一步,如果我允许山姆看到约翰(但没有其他人),因为他们都是100组的成员怎么办?从概念上讲,LinkedIn或Facebook同样允许您在连接后查看有关某人的信息。

这可以通过某种访问控制列表(ACL)来实现。如果用户A因为不是朋友而无法看到B的数据,则查询/users/B将不返回任何内容。但是,如果C(谁是B的朋友)在/users/B上执行相同的请求,他将能够看到B的数据。

所以我会选择第一个选项。

答案 1 :(得分:0)

我会考虑制作一个单独的资源,也许是groupMemberships,它拥有这种关系。你仍然可以拥有像GET / users / 1 / groups这样的东西来直接获得团体,如果它对你有价值的话。

GET /groupMemberships?user=1
GET /groupMemberships?group=100

{
    "href": ".../groupMemberships/abc123"
    "user": {
        "href": "/users/1"
    }
    "group": {
        "href": "/groups/100"
    }
}