我读了很多关于幂等和非幂等的文章,认为我清楚地理解了这个概念。 但是,尽管有POST场景,但仍然让我感到困惑。
POST应该始终创建一个新资源。例如:
POST api/persons { Name: "John" } --> persons/1
POST api/persons { Name: "Jack" } --> persons/2
POST api/persons { Name: "Jack" } --> persons/3
这很明显,但是假设一个人有一个ID作为PK,还有一个SSN,这是唯一的密钥。 在这种情况下,如果我发送具有相同SSN的两个POST请求,则不会创建两个新资源:
POST api/persons { Name: "John", SSN: 123 } --> persons/1
POST api/persons { Name: "Jack", SSN: 123 } --> error
请注意,我没有发送ID PK,因此从理论上讲,POST应该将其视为新资源并创建它。
这是否打破了REST POST非幂等标准?
答案 0 :(得分:1)
POST应该始终创建一个新资源。
这是一个误解-您可以将POST用于其他目的。故意是非常通用的。
这是否违反了REST POST非幂等标准?
否,因为POST 不是必需的。
例如,假设我们要提供一个Web API,该API允许使用者查询数据库中的信息。由于该操作“基本上是只读的”,因此我们可以使用具有safe语义的消息。
通常,我们将使用GET并使用查询字符串来描述查询的参数。
但是,实际上对URI的长度有限制,因此对查询的长度也有限制。如果我们需要支持超出这些限制的查询,我们唯一的选择是将参数移到请求正文中。
标准的“安全” HTTP方法对于请求正文没有明确定义的语义。
因此,为了确保行为正确,我们使用POST而不是GET。在服务器上的效果仍然是“基本上只读”,但是只能看到消息(而不是我们的带外API文档)的通用组件将不知道消息是安全的,并且使用安全方法时将无法执行优化(缓存,自动重新发送,爬网)。
换一种说法,我们在HTTP中所做的一切都可以通过POST完成-其他方法所做的就是允许我们解锁消息的普通使用者/观察者中的优化。
在实践中,HTTP完全不限制实现,它描述了语义。 Roy Fielding在2002年进行了解释:
HTTP不会尝试要求GET的结果是安全的。该操作要求操作的语义是安全的,因此,如果发生任何导致财产损失的结果(钱,BTW,为了这个定义,它被视为财产。)
POST不能保证是幂等的,因此,如果客户认为它确实做出了承诺,那么客户就会被破坏。