更新与 REST 的多对多关联
Posted
技术标签:
【中文标题】更新与 REST 的多对多关联【英文标题】:Updating many-to-many association with REST 【发布时间】:2016-09-18 14:33:19 【问题描述】:我有三个不同的模型,User
、PermissionSet
和 Permission
。这些模型分别代表它们的 SQL 表。
User
具有多对一关联 PermissionSet
,用户可能有一个 PermissionSet
或没有。 PermissionSet
s 将不属于任何一个或多个User
s。
PermissionSet
与Permission
s 具有多对多关联。一个Permission
可以由多个PermissionSet
s 拥有或不拥有,其中PermissionSet
s 可以拥有多个Permission
s 或根本不拥有。
所以我创建了四个表:users
、permission_sets
、permissions
和一个联结表 permission_sets_permissions
。
我需要保留在User
的PermissionSet
中所做的更改。这由一个名为 PermissionSetGrant
的模型处理,它有自己的表 permission_set_grants
。
使用基于 HTTP 和 JSON 的 RESTful API 更改 PermissionSet
的 Permission
s 的最佳方法是什么?
例如,用这样的请求修改PermissionSet
是不是一个好方法:
PUT /api/v1/permission_sets/7
// Payload
"permission_set":
// Assume these properties of the entity aren't changed
"name": "default",
"description": "Default permission set.",
// Here we're changing the permissions
"permission_ids": [
24,
27,
35
]
-> 200 OK
还是使用额外的 REST 路径添加权限?
POST /api/v1/permission_sets/7/permissions
// Payload
"permission": 24
-> 201 CREATED
以及何时需要删除该权限
DELETE /api/v1/permission_sets/7/permissions/24
-> 203 ACCEPTED
我还要补充一点,从客户端的角度来看,请求是幂等的和确定的。权限数至少为 100。因此,批处理操作将在第二种方法中执行。
【问题讨论】:
【参考方案1】:我认为您当前的解决方案还可以。如果您只想将权限与权限集联系起来,那么您可以使用多个 id 来描述集合,而不是使用相同的有效负载,例如
PUT /api/v1/permission_sets/1+2+3/permissions/4+5+6/
DELETE /api/v1/permission_sets/1+2+3/permissions/4+5+6/
如果我是你,我不会拘泥于分层 URI 设计,但大多数时候它很不方便。
PUT /api/v1/permissions/4+5+6/into/permission/sets/1+2+3/
DELETE /api/v1/permissions/4+5+6/from/permission/sets/1+2+3/
请注意,URI 设计没有 REST 约束,因为 REST operates with hyperlinks 和机器客户端。因此,从客户端的角度来看,URI 的结构并不重要,只要它可以用 URI 模板描述即可。唯一需要记住的是,URI 和资源之间存在 n:1 关系,因此多个 URI 可以识别同一个资源,但单个 URI 不能识别多个资源。
【讨论】:
【参考方案2】:如果您要允许一次更新如此大量的权限,那么PATCH
可能是您的朋友:
查看RFC 6902(定义补丁标准),从客户端的角度来看,API 可以这样调用
PATCH /api/v1/permission_sets/7
[
"op": "add", "path": "/permission_ids", "value": [ "24", "27", "35" ]
]
但是,不幸的是,PATCH
不是 idempotent 方法(POST
也不是,原因几乎相同),因此排除后您只剩下 PUT
,这很好,只是比PATCH
更详细一点(客户端必须PUT
整个对象,包括整个permission_ids 集合)。
【讨论】:
以上是关于更新与 REST 的多对多关联的主要内容,如果未能解决你的问题,请参考以下文章