首页 > 解决方案 > 唯一键是否会破坏 POST 非幂等性?

问题描述

我读了很多关于幂等和非幂等的内容,我认为我清楚地理解了这个概念。然而,一个 POST 的场景让我感到困惑。

一个 POST 应该总是创建一个新资源。例如:

  1. POST api/persons { Name: "John" } --> persons/1
  2. POST api/persons { Name: "Jack" } --> persons/2
  3. POST api/persons { Name: "Jack" } --> persons/3

现在这很明显,但是假设一个人有一个作为 PK 的 ID,还有作为唯一密钥的 SSN。在这种情况下,如果我发送两个具有相同 SSN 的 POST 请求,它不会创建两个新资源:

  1. POST api/persons { Name: "John", SSN: 123 } --> persons/1
  2. POST api/persons { Name: "Jack", SSN: 123 } --> error

请注意,我没有发送 ID PK,因此理论上,POST 应该将其视为新资源并创建它。

这会破坏 REST POST 非幂等标准吗?

标签: restpostprimary-keyunique-keyidempotent

解决方案


POST 应该总是创建一个新资源。

这是一种误解——您可以将 POST 用于其他目的。这是故意非常通用的。

这是否违反了 REST POST 非幂等性标准?

不,因为 POST不需要是非幂等的。

例如,假设我们想提供一个 Web API,允许消费者查询数据库中的信息。由于操作“本质上是只读的”,我们可以使用具有安全语义的消息。

我们通常会使用 GET,并使用查询字符串来描述查询的参数。

但是 URI 的长度存在事实上的限制,因此对查询的长度也有限制。如果我们需要支持超出这些限制的查询,我们唯一的选择是将参数移动到请求正文中。

并且标准的“安全”HTTP 方法没有为请求主体定义明确的语义。

因此,为了确保正确的行为,我们使用 POST,而不是 GET。在服务器端的效果仍然是“本质上只读”,但是只能看到消息的通用组件(而不是我们的带外 API 文档),不会知道消息是安全的,并且无法执行优化(缓存、自动重新发送、抓取)在使用安全方法时可用。

换句话说,我们在 HTTP 中所做的一切都可以通过 POST 完成——其他方法所做的是允许我们解锁消息的通用消费者/观察者中的优化。

在实践中,HTTP 根本不限制实现——它描述了语义。这是Roy Fielding在 2002 年的解释:

HTTP 不尝试要求 GET 的结果是安全的。它所做的是要求操作的语义是安全的,因此如果发生任何导致财产损失的事情(金钱,顺便说一句,为了这个定义,被认为是财产)。

POST 不承诺是幂等的,因此如果客户认为它确实做出了这个承诺,他们就会被破坏。


推荐阅读