我不太理解为什么PATCH方法不安全而PUT方法安全。还有幂等性部分 - 如果我更新资源的一个字段,那么更新后该字段不会返回相同的值吗?
我不太理解为什么PATCH方法不安全而PUT方法安全。还有幂等性部分 - 如果我更新资源的一个字段,那么更新后该字段不会返回相同的值吗?
由于一般情况下,执行 PATCH 请求时,无法安全地更改资源 (这就是它的作用),因此不是 安全 的。
那么相对于 PUT,为什么 PATCH 不是 幂等 的呢?这是因为应用更改的方式很重要。如果您想更改资源的 name
属性,则可以发送类似 {"name": "foo"}
的有效载荷,这确实是幂等的,因为执行此请求任意次数都会产生相同的结果:资源的 name
属性现在是 "foo"。
但是 PATCH 在如何更改资源方面具有更大的灵活性(请查看此处关于如何应用 JSON patch 的定义)。例如,它也可能意味着移动资源,并且可能看起来像这样:{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" }
。这个操作显然不是幂等的,因为第二次调用会导致错误。
因此,虽然大多数 PATCH 操作可能是幂等的,但有些操作不是。
关于其他回答的一点说明:幂等性是通过多次重复操作来定义的。说某个操作不是幂等的,因为在其中执行了其他操作或并行操作导致效果不同,这不是一个有效的论据(如果是这种情况,通常没有任何操作会是幂等的)。从数学上讲,幂等变换是一种无论你如何多次应用都会产生相同结果的变换(就像将某物旋转360度)。当然,如果在两次360度旋转之间执行了其他操作,则可能会产生不同的结果。
{"op": "add", "path": "/-", "value": "foo"}
第一次将 []
转换为 ["foo"]
,第二次将其转换为 ["foo", "foo"]
,第三次将其转换为 ["foo", "foo", "foo"]
等。 - Géry Ogam最近我开始思考 Patch 是否具有幂等性,经过阅读 JSON patch 格式的相关内容,我了解到如果使用 Patch 方法进行添加操作,则请求可能是非幂等的,因为如果多次发出相同的请求,它可以向现有资源添加新值。
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }
PATCH修改资源的属性。更改可能需要属性的具体先前值,这使得它非幂等。
From Name=John to Name=Gargantua.
经过多次更改,名称将变为Gargantua,补丁将失败,因为在更改之前需要将名称设为“John”。
"from Name=John"
首先,PUT
也不安全。
安全方法是指不修改资源的HTTP方法。例如,在资源URL上使用GET或HEAD,永远不应更改资源。
由于PUT
请求(以及PATCH)更新了资源,因此无法缓存,因此不安全。
PUT
请求虽然幂等,或者说PUT
请求应该是幂等的。
幂等的HTTP方法是指可以重复调用多次而没有不同结果的HTTP方法。方法只调用一次或十次都没有关系,结果应该是相同的。同样,这仅适用于结果,而不是资源本身。这仍然可以被操作(例如更新时间戳,只要这些信息未在当前资源表示中共享即可)。
PUT
请求被认为是幂等的,其背后的思想是,如果对资源的更新调用失败,客户端可以再次进行相同的调用,而不会导致任何不良或不一致的状态。PUT
请求应始终在资源之前进行GET
请求,并且仅当资源未更改时才应成功。详见:阅读类似答案之一-并发环境中的幂等PUT请求
现在,PATCH
请求旨在仅更新选择性字段,不需要获取资源表示。因此,多次调用PATCH
请求可能会导致资源状态的不良变化。因此它不是IDEMPOTENT
。
例如:
有一个资源Person
请求1: PATCH /person/1 {'age': 10} - 将资源的年龄更新为10
现在假设其他并行请求更改了资源的状态,比如
请求2: PATCH /person/1 {'age': 19} - 将资源的年龄更新为19
现在,如果再次发送请求1,则会将资源的年龄再次更新为10,从而导致不良结果。
但是可以使用ETags或If-Modified-Since头使其幂等。