REST - PUT 方法在省略可选字段时是否必须删除该字段?

eth*_*b_0 5 rest put http-method

我有一个资源Car,其中有一些必填字段和另一个可选字段。

Car是根据以下请求创建的:

POST /cars
{
  plate: "XYZ-A2C4",
  color: "blue,
  owner: "John" //OPTIONAL
}
Run Code Online (Sandbox Code Playgroud)

REST 客户端想要更新这辆车的所有必需信息:

PUT /cars/:id
{
  plate: "ABC-1234",
  color: "black"
}
Run Code Online (Sandbox Code Playgroud)

可选字段会发生什么情况owner

  • 没有通知就被删除了?即:PUT 必须用有效负载中传递的表示替换整个资源?
  • 或者,由于owner不需要,服务器可以保留旧值?


我知道服务器可以提供一种PATCH方法,但有时无法更新单个字段,因为新状态可能会变得无效(没有强制执行相关字段值所需的最低有效负载)。此外,在某些情况下,操作数组、删除字段或设置它null可能会很棘手,PATCH因为它可以使用两种不同的模式来完成;JSON Merge Patch 是有限的,并且 JSON Patch有点奇怪


是否可以使用PUT必填字段执行 a 并且服务器在省略该字段时保留旧的可选值?

Eri*_*don 5

如果您想按照书本(RFC 7231 的第 4.3.4 节)进行操作,那么是的,在您的情况下,PUT 请求应该替换整个Car资源:

PUT 方法请求创建目标资源的状态或用请求消息有效负载中包含的表示定义的状态替换目标资源的状态。给定表示的成功 PUT 表明对同一目标资源的后续 GET 将导致在 200 (OK) 响应中发送等效的表示。

因此,根据书本,您不应该使用 PUT 进行部分更新,而应该使用 PATCH。

然而,在实践中,这实际上取决于您来决定这如何准确地应用于您的服务,更重要的是,记录它。

以下是一些实际示例,说明一些知名 API 如何允许部分更新:

  • Ghost API不支持部分资源更新,任何更新都需要包含完整资源的 PUT 请求
  • Rossum API支持 PATCH 进行部分资源更新,但其文档明确指出仅支持顶级属性
  • GitHub允许 PATCH 和 POST 请求进行部分数据更新
  • Firebase允许 PATCH 请求,但也允许使用 X-HTTP-Method-Override 标头进行 POST

您是完全正确的,有时,PATCH如果按原样处理,方法可能会导致无效资源。然而,没有什么可以阻止服务器确保正确的数据状态作为副作用。因此,在每次调用期间,您都可以让服务器:

  • 在持久化资源之前验证资源的正确状态
  • 拒绝(带有 400 Bad Request 错误)任何会导致不正确状态的请求
  • 成功后用资源做出响应(可能会产生副作用)