HTTP PATCH是幂等的还是非幂等的?

时间:2015-03-21 18:44:14

标签: rest idempotent

我已经阅读了很多HTTP Patch非幂等的地方。有人可以解释一下为什么它是非幂等的吗? 因为根据定义 - 幂等方法可能会也可能不会更改资源状态,但重复请求在第一次请求后应该没有其他副作用。 重复的PATCH请求如何更改资源状态?

3 个答案:

答案 0 :(得分:5)

对此存在一些困惑。 PATCH方法不是必需是幂等的,这就是重点。客户端不能假设他们的PATCH请求是幂等的,因为他们可以使用PUT和GET。

如果特定实现是幂等的,通常取决于所使用的修补算法,如果有的话。例如,不使用验证当前值的diff格式的不良实现不会是幂等的。

答案 1 :(得分:1)

我有一个场景,其中PATCH不是幂等的:

让我们假设两个不同的客户端正在发送HTTP请求 客户X
客户Y

客户X
(1)PATCH {“年龄”:“10”}
response1-> {“age”:“10”,“sex”:“f”,“name”:“a”}

客户Y
(2)PATCH {“name”:“b”}
response2-> {“age”:“10”,“sex”:“f”,“name”:“b”}

客户X
(3)PATCH {“age”:“10”}
response3-> {“age”:“10”,“sex”:“f”,“name”“b”}

您可以看到,即使请求(1)和(3)相同,响应也会有所不同。第3个回复中的“name”“b”

如果这是一个有效的场景,它可以证明即使请求相同,PATCH方法也可以响应不同的响应。 使用PUT方法永远不会发生这种情况,PUT方法应该发送包含所有字段{age,sex,name}的整个对象。

答案 2 :(得分:1)

是的,有很多讨论和混淆 PUT 和 PATCH 的区别。明确的是:

放置

  • 请求必须包含给定资源的完整表示
  • 是幂等的(客户端可以100%确定)

补丁

  • 请求只包含子集(只是我们想要更新的属性)
  • 不需要是幂等的(通常是幂等的,但这不是规则,因此客户端不能100%确定)

从这些规则中,我们可以推导出一些我们需要在后端实现的规则,例如:

a)

  • 获取:users/1;响应正文 {from flask import abort @app.route('/example/<int:id>', methods=['GET']) def tasks(id): if id == 1: obj = FirstTask() elif id == 2: obj = SecondTask() elif id == 3: obj = ThirdTask() else: abort(404) result = obj.start() return make_response(jsonify({ 'data': { result } }), 200) }
  • PUT:users/1;请求正文 {username: 'john', email: 'old@email.com'}

从 API 发送验证错误(缺少 username: 'john')或电子邮件将被删除。

我真的希望 API 应该返回验证错误。因此,要删除某个值,客户端应调用(请求中明确提到的 email):

  • PUT:users/1;请求正文 {email: null}

b)

  • 补丁:users/1;请求正文 {username: 'john', email: null}

服务器上没有变化。要删除值,客户端应发送:

  • 补丁:users/1;请求正文 {username: 'john'}

上面的两个例子都是幂等的。

在另一个讨论中,如果补丁正在对后端的集合执行诸如“添加”之类的操作,则 PATCH 是非幂等的:Use of PUT vs PATCH methods in REST API real life scenarios