【问题标题】:REST: How to support create-Or-Update and partial-update ? (aka PUT vs PATCH)REST:如何支持 create-Or-Update 和 partial-update ? (又名 PUT 与 PATCH)
【发布时间】:2019-09-24 02:31:47
【问题描述】:

我们正在为用于管理电子商务产品信息的软件设计 WebAPI。我们希望提供(除其他外)两种操作:

  1. 简单一:允许用户添加/修改现有产品信息:
    • 如果新产品不存在就不要创建它
    • 请勿从现有产品中删除此请求中未提供的任何信息

在我看来,HTTP PATCH 方法是处理这种情况的正确方法(使用 json-patch 或 json-merge-ptach),其 URL 如下:/products/{ID}

  1. 更难的一个:允许用户添加/修改现有产品或创建一个
    • 如果数据库中不存在则创建产品
    • 不要从现有产品中删除此请求中未提供的任何信息(与第一种情况相同)

我正在努力为第二个用例设计 REST 端点。我的选择很少,但没有一个完全适合我的 REST 原则:

  • a) 将自定义 HTTP 标头添加到为第一种情况(补丁)设计的端点,以允许调用者控制“未找到的行为”,例如。 create-entity-when-not-exists: true/false - 但我认为 PATCH 不应该用于创建资源。

  • b) 使用带有特殊标头“preserve-not-provided-data”的 PUT 设计新端点 - 另一方面,这违反了 PUT 原则,因为 PUT 是创建或替换而不是创建或更新方法

  • c) 为 /products URL 创建 PATCH(末尾不带 {ID}) - 在这种情况下,我们正在更新产品的整个集合(资源) - 所以如果产品存在,我们可以更新它或创建新的如果不存在。

现在 c) 解决方案对我来说很好,但有一个例外:如果将来我们想支持批处理操作(对于两个用例:1 和 2),我们想使用 /products URL,它会与来自解决方案 c) 的 URL

你怎么看?您还有其他想法吗?

【问题讨论】:

  • 正如Jim Webber 所说,您不会在 REST 中“调用”,您只需随机播放文档。触发的业务规则只是文档管理的副作用。您的工作是设计一个客户将遵循的应用程序域协议,就像人类在从亚马逊或其他商店网站订购时所做的那样。您应该使用表单(只需查看 Web)向客户端介绍服务器期望的输入和链接,以允许客户端通过客户端将通过的应用程序域状态机进行处理

标签: rest


【解决方案1】:

PUTPATCH 具有不同的消息语义,但核心上下文(“远程创作”)是相同的。在这两种情况下,客户端请求都是“请,服务器,使您对此资源的表示与我的本地副本相匹配”。

例如,我 GET 来自服务器的 JSON 文档。我对其进行本地编辑。现在我想在服务器上“保存”我的更改。如果文档大小适中,我可能会通过网络发送整个修改后的文档。如果文档很大,而我的改动不大,那么我可能会改为发送补丁。

如果您设想使用 HTTP 将 HTML 网页的编辑内容发布到服务器,那么您就有了正确的参考框架。 “请修补文档副本的标题”和“这是文档的完整新副本,我对标题进行了编辑”之间没有太多实际区别。无论哪种情况,磁盘上的字节都是相同的。

鉴于此,如果这两种发布文档新修订版的方法会产生截然不同的副作用,那就太奇怪了。

基于修改/products 的第三种方法可能对您的个人和批量都适用。服务器获取/products 的新表示(或描述更改的补丁文档),决定是否接受更改,如果接受,则计算它需要对自己的数据库执行哪些操作才能使事情正常进行。

注意:

应用于目标资源的 PUT 请求可能会对其他资源产生副作用。

HTTP 规范对消息的含义 的含义相对严格,但在响应的行为方式方面为服务器提供了很大的余地。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 2012-09-02
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    相关资源
    最近更新 更多