我正在尝试了解 PUT 和 PATCH 之间的区别。
从“它们有何相同之处?”开始
PUT 和 PATCH 都用于远程创作环境;我们使用这些消息语义来告诉服务器使其自己对某些资源的表示看起来像我们的本地副本。
例如,如果我想更改网站首页的标题,我可以
GET /home.html
将当前版本加载到我的 HTML 编辑器中。然后我可以对我的本地副本进行更改。为了发布我的更改,我向服务器发送了一条消息“让您的副本像我的副本一样”。
使用 PUT,请求的有效负载是我的文档版本的完整副本。我将整个文档发送回服务器进行处理。
使用 PATCH,我创建了一个“补丁文档”,也就是说,我使用服务器可以理解的某种媒体类型来表示我的更改。服务器应该通过将补丁文档应用到其本地副本来为自己计算新的表示。
PUT 具有idempotent 语义;这意味着通用组件(如 Web 浏览器和反向代理)知道连续收到的同一请求的多个副本与该请求的单个副本具有相同的含义。这意味着,在请求或响应可能丢失的网络故障事件中,我们可以自动重新发送请求。
PATCH 不承诺幂等处理——即使补丁文档描述了对资源的幂等更改,通用组件也不会知道重新发送请求是安全的。
另一方面,如果您的文档较大(相对于 HTTP 标头的大小)并且您的更改很小,那么补丁文档将小于完整的表示;如果网络足够可靠,较小的请求可能比可重复的请求具有更好的投资机会。
当然,您最灵活的做法是同时支持这两种方法,并在对OPTIONS 请求的响应中描述这两种方法以及您支持的补丁格式的媒体类型。这允许客户根据自己的本地环境选择适当的方法。
PATCH 需要比 PUT 更高的兼容性,因为客户端和服务器都需要了解相同的补丁媒体类型(除了了解表示本身的媒体类型)。
因此,您可能最好使用 PUT,然后在客户端需要优化的情况下使用 PATCH 作为替代方案,而不是相反。
如果您正在做一些非常具体的事情,那么一般准则可能不适用。
例如,如果您正在实现一个 JSON:API,用于 JSON:API 客户端,那么您将要使用 PATCH,因为 JSON:API 在 the use of PUT 和 application/vnd.api+json 上有一个相当特殊的位置指定如何将其用作补丁文档。因此,关于客户端和服务器理解相同补丁表示的担忧“消失了”。