更新与REST的多对多关联

时间:2016-09-18 14:33:20

标签: rest restful-architecture restful-url api-design httpverbs

我有三个不同的模型UserPermissionSetPermission。这些模型分别代表它们的SQL表。

User具有多对一关联PermissionSet,用户可能只有一个PermissionSet或没有关联。 PermissionSet s将由无人或许多User s拥有。

PermissionSetPermission有多对多关联。 Permission可以归多个PermissionSet所有,PermissionSet可能拥有多个Permission,或者根本没有。{/ p>

所以我创建了四个表:userspermission_setspermissions和联结表permission_sets_permissions

我需要保留User PermissionSet中所做的更改。这由名为PermissionSetGrant的模型处理,该模型有自己的表permission_set_grants

基于HTTP和JSON,使用RESTful API更改Permission的{​​{1}}的最佳方法是什么?

例如,使用此类请求修改PermissionSet是一种好方法:

PermissionSet

或者使用额外的REST路径添加权限?

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

当我们需要删除该权限时

POST /api/v1/permission_sets/7/permissions

//  Payload
{
    "permission": 24
}

-> 201 CREATED

我还要补充一点,从客户端的角度来看,请求是幂等的和确定性的。权限数量至少为100。因此,批处理操作将以第二种方式执行。

2 个答案:

答案 0 :(得分: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/

请注意,自REST operates with hyperlinks和机器客户端以来,没有关于URI设计的REST约束。因此,从客户端的角度来看,只要可以使用URI模板描述URI,URI的结构并不重要。您唯一需要记住的是,URI和资源之间存在n:1关系,因此多个URI可以标识相同的资源,但是单个URI无法识别多个资源。

答案 1 :(得分:0)

如果您要允许一次更新如此大量的权限,那么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 1}},这很好,比 $zip->open('myFile.zip'); (客户端必须 $zip->open($myFile); 整个对象(包括整个permission_ids集合)更冗长。