如何设计REST API,需要资源创建和修改才能被另一方批准

use*_*232 2 rest

我必须为需要双重控制的安全敏感资源设计REST服务.设计实现双重控制的REST服务的优雅方法是什么?

双重控制

对于双重控制,我的意思是,如果多人(例如2人)参与变更,则变更才会生效.

例如,我有一个名为userProfile的资源.它定义了允许用户执行的所有操作.如果有人想要更改此类个人资料,则可以建议对其进行更改.然后必须验证此更改.此验证的结果是"批准"或"拒绝".一旦变更获得批准,它就会生效.

设计

我目前有一个userProfile资源和一个userProfileChangeProposal资源.

创建一个创建userprofile的提议

POST /userprofiles
Run Code Online (Sandbox Code Playgroud)

这将返回userprofile的ID.现在可以使用{id}进行验证

PUT /userprofiles/{id}/changeproposal
Run Code Online (Sandbox Code Playgroud)

删除或更新userprofile需要再次提交,因此:

DELETE /userprofiles/{id}
PUT /userprofiles/{id}
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式再次验证这些更改:(对于用户配置文件,同时只能有1个提案)

PUT /userprofiles/{id}/changeproposal
Run Code Online (Sandbox Code Playgroud)

问题

我正在努力的事情是,其余的操作似乎在userprofile资源上运行,但事实上他们不这样做.删除不会直接删除资源.它会创建一个删除它的提议.此外,此方法不允许直接删除用户配置文件.

另一方面,如果通过更改提议进行所有更改,则所有创建/删除/更新操作都是正确的

CREATE /userprofilechangeproposal
Run Code Online (Sandbox Code Playgroud)

我没有在互联网上看到有关双控制设计的任何内容.最接近的是有人首先创建ORDER资源,并且只有在订单被批准后才会创建实际的CAR.

任何人都有最佳做法?

jan*_*nis 6

我想这篇关于Rest Cookbook的文章回答了你的问题.同样的文章,但在这里这里可以找到更多的冗长.

总结URL中的信息,您的工作流程应如下所示:

  1. 用户使用/userprofiles有效负载中的配置文件信息发送POST { "username": "user1298232" }(作为示例)

  2. 该服务回复202 AcceptedLocation: /proposals/12345标题.

  3. 用户可以通过发送GET /proposals/12345请求来检查提案状态.此资源可能如下所示{ "status": "waiting for approval" }

  4. 当接受并创建实际资源(例如,id为1)GET /proposals/12345不再返回状态,而是将请求重定向(带有303响应状态代码和Location标头)到新创建的资源/userprofiles/1.

    4A.稍后客户端可以删除提议资源,或者服务器可以使其到期并返回410 Gone(在一段时间后作为垃圾收集的元素).

    4B.如果提案被拒绝,那么其状态应相应地改变(例如{ "status": "Rejected" }).

注意(来自文章):

创建资源时,请勿使用301或302.这些代码告诉客户端可以在其他位置找到SAME资源.303告诉客户端可以在另一个位置找到另一个资源.

可以使用相同的工作流来修改/删除资源.

编辑:批准提案

我忘了写如何批准请求.最自然的方法是授权用户发送部分更新,PATCH /proposals/1包括状态更改 - { "status": "approved" }.

讨论了PATCH请求的有效负载应该如何.描述部分更新的上述方法(仅包括要更新的属性的部分资源)例如在GitHub API中实现,GitHub API被许多人认为是RESTful API的角色模型.呈现在这里是另一种方法,这需要有效载荷来形容变化本身,而不是与属性的部分资源更新:{ "op": "replace", "path": "/status", "value": "approved" }.

PATCH 还不是官方的HTTP方法,所以理论上它可能会在某些环境中导致某些问题,但我还没有遇到过这种情况(根据这篇SO帖子的评论表明MS Edge中的PATCH可能存在问题,但是我没有检查过).无论如何,你可以设计/proposals/[id]接受PUT请求只是为了安全起见.请记住,PUT应该替换资源,并且应该包含有效负载中的整个资源,而不仅仅是已更改的属性.

编辑2

关于PATCH问题:似乎GitHub API实际上允许使用POST进行部分更新,因为上面提到的可能与某些客户端的PATCH不兼容.因此,除了正常职责(资源创建)之外,POST还会在给定资源ID(link - > section HTTP Verbs)时获得部分更新功能:

PATCH - 用于使用部分JSON数据更新资源.例如,Issue资源具有title和body属性.PATCH请求可以接受一个或多个属性来更新资源.PATCH是一个相对较新且不常见的HTTP动词,因此资源端点也接受POST请求.