如何设计一个RESTAPI,它需要资源的创建和修改得到另一方的批准

如何设计一个RESTAPI,它需要资源的创建和修改得到另一方的批准,rest,Rest,我必须为需要双重控制的安全敏感资源设计REST服务。设计实现双重控制的REST服务的优雅方式是什么 双重控制 对于双重控制,我的意思是,只有当多人(例如2人)参与变更时,变更才会生效 例如,我有一个名为userProfile的资源。它定义了用户可以做的所有事情。如果有人想要更改这样的配置文件,它可以建议对其进行更改。然后必须验证此更改。此验证的结果为“批准”或“拒绝”。变更一经批准即生效 设计 我目前有一个userProfile资源和一个userProfileChangeProposal资源 创

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

双重控制 对于双重控制,我的意思是,只有当多人(例如2人)参与变更时,变更才会生效

例如,我有一个名为userProfile的资源。它定义了用户可以做的所有事情。如果有人想要更改这样的配置文件,它可以建议对其进行更改。然后必须验证此更改。此验证的结果为“批准”或“拒绝”。变更一经批准即生效

设计 我目前有一个userProfile资源和一个userProfileChangeProposal资源

创建建议以创建用户配置文件通过

POST /userprofiles
这将返回userprofile的ID。现在可以使用该{id}进行验证

PUT /userprofiles/{id}/changeproposal
删除或更新userprofile需要再次提交建议,因此:

DELETE /userprofiles/{id}
PUT /userprofiles/{id}
可以通过以下方式再次验证这些更改:(一个userprofile在同一时间只能有一个提案)

问题 我正在努力解决的问题是,rest操作似乎在userprofile资源上运行,但事实上它们并没有。删除不会直接删除资源。它会创建一个建议来删除它。 此外,这种方法不允许直接删除用户配置文件

另一方面,如果所有更改都是通过更改建议进行的,那么所有创建/删除/更新操作都只是

CREATE /userprofilechangeproposal
我在网上没有看到任何关于双控设计的东西。最接近的例子是,有人首先创建了一个订单资源,只有在订单得到批准后,才创建了实际的汽车

有人有什么最佳实践吗?

我想这回答了你的问题。相同的文章,但更详细一点可以找到和

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

  • 用户向
    /userprofiles
    发送一篇文章,其中包含有效负载
    {“username”:“user1298232”}
    中的配置文件信息(例如)

  • 服务以
    202已接受
    位置:/propositions/12345
    标题答复

  • 用户可以通过发送
    GET/provides/12345
    请求来检查提案状态。此资源可能如下所示
    {“状态”:“等待批准”}

  • 当实际资源已被接受并创建(例如id为1)时,
    GET/propositions/12345
    不再返回状态,而是将请求重定向(使用
    303
    响应状态代码和
    Location
    头)到
    /userprofiles/1
    处新创建的资源

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

    4b。如果提案被拒绝,则其状态应相应更改(例如,
    {“状态”:“已拒绝”}

  • 注(摘自文章):

    创建资源时不要使用301或302。这些代码告诉客户机可以在其他位置找到相同的资源。303告诉客户机可以在另一个位置找到另一个资源

    同一工作流可用于修改/删除资源

    编辑:批准提案 我忘了写如何批准请求。最自然的方法是授权用户发送部分更新
    补丁/建议/1
    ,包括状态更改-
    {“状态”:“已批准”}

    有一个关于补丁请求的有效负载应该是什么样子的讨论。上述描述部分更新(仅包括要更新的属性的部分资源)的方法被实现,例如,其中许多人认为是restfulapi的角色模型。提出了另一种方法,它要求负载描述更改本身,而不是使用要更新的属性描述部分资源:
    {“op”:“replace”,“path”:“/status”,“value”:“approved”}

    补丁,所以理论上它可能会在某些环境中导致一些问题,尽管我个人还没有遇到过这种情况(下面的评论表明MS Edge中的补丁可能有问题,但我还没有检查)。无论如何,为了安全起见,您可以设计
    /propositions/[id]
    来接受PUT请求。请记住,PUT应该替换资源,并且应该在有效负载中包含整个资源,而不仅仅是更改的属性

    编辑2 关于补丁问题:似乎GithubAPI实际上也允许使用POST进行部分更新,因为上面提到的补丁可能与某些客户端不兼容。因此,POST除了其正常职责(资源创建)外,还可以在给定资源ID(->HTTP动词部分)时获得部分更新功能:

    补丁-用于使用部分JSON数据更新资源。例如,问题资源具有标题和正文属性。补丁请求可以接受一个或多个属性来更新资源。补丁是一个相对较新且不常见的HTTP动词,因此资源端点也接受POST请求


    詹尼斯,谢谢你花时间广泛地回答我的问题。异步方法和一个可接受的参数似乎适合我的情况。如果将来我想让某些(自动化的)进程能够在没有双重控制的情况下编辑资源,REST服务可以决定是返回202还是201。至于批准本身,我还看到了对提案资源上的“决策”子资源建模的实现。请求可以通过/userprofiles/{id}/changeproval/decisionI not上的帖子进行验证
    CREATE /userprofilechangeproposal