15

我最近花了很多时间阅读 HTTP 1.1 规范并将其与 REST 相关联。我发现对于 HTTP DELETE 方法的“幂等性”和安全性有两种解释。以下是两个阵营:

  1. 如果您使用 HTTP DELETE 删除资源,并且成功(200 OK),然后您尝试删除该资源 N 次,您应该为每个删除调用返回一条成功消息(200 OK) . 这就是它的“幂等性”。

  2. 如果您使用 HTTP DELETE 删除资源,并且成功(200 OK),然后您尝试再次删除该资源,您应该会收到一条错误消息(410 Gone),因为该资源已被删除。

规范说 DELETE 是幂等的,当然,但它也说幂等事件的序列仍然会产生副作用。我真的觉得第二个阵营是正确的,而第一个是误导性的。通过允许客户认为他们是删除先前删除的资源的原因,我们引入了哪些“安全性”?

第一个阵营有很多人,包括这个主题的几位作者,所以我想检查是否有一些令人信服的理由,而不是情绪导致人们进入第一个阵营。

4

3 回答 3

21

幂等并不意味着不允许请求有副作用(这就是“安全”属性所描述的)。这只是意味着多次发出相同的请求不会导致不同或额外的副作用。

在我看来,随后的 DELETE 请求应该返回一个错误 - 它仍然是幂等的,因为服务器的状态与只发出一个 DELETE 请求相同。然后再次返回 200 OK 状态也应该没问题 - 我认为幂等不需要为后续的 DELETE 请求返回错误代码 - 只是返回错误状态对我来说似乎更有意义。

于 2009-04-12T02:51:13.917 回答
2

@MichaelBurr 关于幂等性和副作用是正确的。

我的观点是,给定的 REST 请求涉及两种状态,即客户端状态和服务器状态。REST 就是在服务器和客户端之间传输这些状态,以便客户端的状态映射到服务器状态的子集,换句话说,子集与服务器保持一致。因为这种幂等性应该意味着后续的幂等请求不会导致任何一个状态与仅发出一次请求不同。使用第一个 DELETE,您可以想象服务器删除资源并让客户端知道它也可以删除资源(因为资源“不再存在”)。现在这两个状态应该与之前相同,减去已删除的项目。为了让客户端在尝试删除已删除的项目时做任何不同的事情,那么从服务器传输到客户端的状态必须包含不同的信息。服务器可以对资源已经被删除的信息做一些稍微不同的事情,但是一旦它用不同的东西做出响应,方法的幂等性就基本上被破坏了。

对于幂等函数:

delete(client_state) -> client_state - {item}
delete(delete(client_state)) -> client_state - {item}
delete(client_state) = delete(delete(client_state))

保证这种幂等性的最好方法是如果服务器的响应是相同的,这意味着客户端状态打破幂等性的唯一方法是在客户端处理响应时存在不确定性或副作用(这可能指向处理响应的错误实现)。

如果客户端和服务器之间就状态代码存在于正在传输的状态表示(REST)之外的协议达成一致,则可以通知客户端该项目“不再存在”(因为它会在第一个请求中)以及先前已删除的额外评论。客户端如何处理这些信息尚不清楚,但它不应该影响生成的客户端状态。但是状态码不能用于传达状态,或者更确切地说,如果它在其他情况下也传达状态(例如“您无权删除此项目”或“项目未删除”),那么有一些引入歧义或混乱。所以,并且仍然让服务器的响应取决于先前相同的 DELETE 请求。

HTTP 请求涉及删除方法,因此该函数可能类似于

delete(client_state) = send_delete(client_state) -> receive_delete(client_state) 
                                                 -> respond_to_delete(informative_state) 
                                                 -> handle_response(informative_state) 
                                                 -> client_state - {item} 
于 2012-10-22T18:58:01.500 回答
0

维基百科将幂等性定义为:

可以多次应用而不改变初始应用之外的结果。

请注意,他们谈论的result是操作。对我来说,这包括服务器状态响应代码。

HTTP 规范在这个问题上有点模糊。它定义它指定 HTTP 方法是幂等的:

如果多个相同请求的预期效果与单个请求相同。

如果您effect按照result维基百科的定义进行解释,那么它们的含义相同。无论如何,我质疑告诉客户资源已被删除的实际好处。

最后一点:幂等性是根据单个客户端定义的。一旦你开始引入其他客户端的并发请求,所有的赌注都没有了。您应该使用条件更新标头(例如If-Match-ETag)来处理这种情况。

重申一下:您应该返回相同的返回码,无论资源刚刚被删除、被先前的请求删除,还是根本不存在。

于 2013-10-15T07:14:43.670 回答