2

我了解,对于部分更新,必须采取非幂等的操作。为此,一种有效的方法是对该资源发出 POST 请求。

我有一个关于相关资源的问题。例如,想象以下资源及其属性:

  1. Accounts
    Id
    Name
    Account #
    用户(一个集合)

  2. 用户
    ID
    名称

现在想象一下,我想对帐户进行部分更新 - 例如,更改帐户的名称。

我可以提出以下请求作为有效的部分更新:

POST /account/id/123

{
    "name" : "My New Name"
}

我的问题是关于一个完整的 PUT 请求,它必须是幂等的,并且必须包含资源的完整表示

我可以将以下作为有效的幂等请求吗?

PUT /account/id/123

{
    "name" : "My New Name",
    "accountNumber" : "654-345-4323"
}

这被认为是一个有效的、幂等的动作吗?我已经包含了所有顶级“帐户”信息,但我质疑它,因为我没有发布所有USERS属于该帐户的信息。

为了成为有效的幂等请求,我是否需要在 PUT 请求中也包含它的所有子资源?

4

2 回答 2

1

如果您想将 PUT 请求设计为完整的资源替换,那么这意味着您还需要为资源的所有可分配(可编辑)属性分配值,包括资源的关系(链接)。否则,未设置的属性将被视为设置为null

对于部分请求,您可以使用 PATCH HTTP 方法。如果您的资源表示足够简单以允许这样做,那么还有一个 PUT 约定,您可以使用部分更新。

补丁与放置

报价:

补丁与放置

HTTP RFC 规定 PUT 必须采用全新的资源表示作为请求实体。这意味着,例如,如果仅提供某些属性,则应删除这些属性(即设置为 null)。

最近提出了一种称为 PATCH 的附加方法。此调用的语义类似于 PUT,因为它更新资源,但与 PUT 不同的是,它应用增量而不是替换整个资源。在撰写本文时,PATCH 仍是等待最终批准的拟议标准。

对于简单的资源表示,差异通常并不重要,许多 API 只是将 PUT 实现为 PATCH 的同义词。这通常不会带来任何问题,因为您需要将属性设置为 null 并不常见,如果需要,您始终可以显式包含它。

然而,对于更复杂的表示,尤其是包括列表,能够准确地表达您想要进行的更改变得非常重要。因此,我现在建议同时提供 PATCH 和 PUT,并让 PATCH 进行相对更新并让 PUT 替换整个资源。

重要的是要意识到 PATCH 的请求实体与它正在修改的实体具有不同的内容类型。它不是完整的资源,而是描述要对资源进行的修改的资源。对于本文所提倡的 JSON 数据模型,我相信有两种合理的方式来定义补丁格式。

  1. 一种非正式的方法,您接受带有对象部分表示的 dict。仅更新存在的属性。不存在的属性将被单独保留。这种方法很简单,但它的缺点是如果资源具有复杂的内部结构,例如包含一个大的字典列表,那么需要在实体中给出整个字典列表。有效地 PATCH 再次变得类似于 PUT。
  2. 更正式的方法是接受修改列表。每个修改都可以是一个字典,指定要修改的节点的 JSON 路径、修改('add'、'remove'、'change')和新值。
于 2015-04-04T18:18:31.743 回答
1

一个更容易理解的方法是认为 PUT 方法忽略了目标资源的当前状态,因此“完整资源表示”意味着它必须具有用新资源替换现有资源所需的所有数据。

在您的示例中,这可能是没有用户的帐户的有效完整表示。

当缺少某些内容时,服务器可以采用默认值,但这应该正确记录,因为某些用户可能会与部分更新混淆。

于 2015-04-04T23:19:01.920 回答