无法删除最后一个联系人 - 哪个 Http 状态码?

8

我目前正在构建一个Web API,有一个特定的场景,我无法确定应返回哪个HTTP状态码最合适。

场景描述

我有一个"客户端"资源,它拥有一组联系人资源。

不变的是,客户端必须始终至少拥有一个联系人。因此,如果发出删除联系人的请求,并且该联系人是给定客户端的最后一个联系人,则需要返回适当的HTTP响应,指示请求无法实现,因为“不能删除最后一个联系人”。

我的感觉是,这应该属于“4xx客户端错误”的范畴。

我考虑了以下状态码:

400错误请求 - 我排除了这个选择,因为它专门处理服务器无法理解的格式错误请求。

405方法不允许 - 起初似乎这个很合适,但我认为405表示这种方法永远不应被允许,然而上述场景只是暂时的。你怎么看?

409冲突 - 我更倾向于这个选择,但通常给出此代码的常见示例是并发异常/编辑冲突。

有没有人能够指导我在这种情况下应该如何响应?


在这种情况下,“409”得到我的支持,因为它是用户可以解决的冲突。常见示例是其他事情对我来说并不重要,类似这个示例的其他示例也存在。确实不应该使用“400”,但如果您使用实际的“DELETE”请求,则可以考虑使用“405”。如果没有,我会推荐使用“409”,但是如果您使用了,我理解您的困境。 - Wrikken
是的,我在这里使用DELETE动词,但我认为405表示该方法不应该在给定资源上被允许。 - jflood.net
1个回答

9
关键是要看客户端和缓存在使用特定状态码时的期望。以下是一些有用的RFC2616片段:
10.4.1. 400 Bad Request 由于格式错误,服务器无法理解请求。客户端不应该在没有修改的情况下重复请求。
这表明请求本身是完全错误的 - 无论是语法上还是协议上。您的具体情况确实是应用程序协议错误,因此可能是适当的。
10.4.6. 405 Method Not Allowed 请求行中指定的方法不允许用于请求URI标识的资源。响应必须包括一个Allow头,其中包含所请求资源的有效方法列表。
这是一个临时状态码。如果DELETE请求特指联系人资源本身(例如,DELETE /contacts/D9DF5176-EEE4-4C70-8DA7-BA57B82027A8),那么这可能是最合适的状态码。但是,如果DELETE请求针对的是不同的资源或带有查询的资源(例如,DELETE /contacts?index=12),那么就不应返回405状态码。再说了,我通常避免使用任何类似查询的DELETE请求。
10.4.10. 409冲突 由于资源的当前状态与请求存在冲突,无法完成请求。只有在预期用户可以解决冲突并重新提交请求的情况下才允许使用此代码。响应正文应包含足够的信息,以便用户识别冲突的来源。理想情况下,响应实体将包含足够的信息,以便用户或用户代理修复问题;但这可能不可能且不是必需的。
这似乎是最合适的状态,但在您的情况下我可能更喜欢使用400。409会清楚地表明资源存在冲突,但请求者无法做出任何改变结果的行为,除非完全改变资源(例如,首先添加联系人)。大多数409响应都是乐观并发失败,例如尝试修改自检索以来已被修改的资源。例如,请查看通过Apache Adbera构建的AtomServer返回的并发失败
所以基于以上理由,我可能会使用"400不能删除最后一个联系人"作为响应行。请记住,您可以更改与状态码相关联的短语。这是非常好的时机。

感谢您的回复D.Shawley,我犹豫使用400的原因是因为定义明确指出“由于语法错误”。您似乎正在扩大这个定义以包括应用程序协议。您有任何支持这种解释的参考资料吗? - jflood.net
你还说Method Not Allowed是短暂的。在我的情况下,每个联系人也是它自己的资源,因此它们都有自己的Uri,所以按照你的论点,我可以使用这段代码。然而,这个状态码的定义并没有真正表明它是短暂的。我为那些永远不能被删除的资源返回这个状态,例如客户端资源本身。 - jflood.net
好的,在与一些同事讨论后,我们决定选择405。我将其标记为正确答案,因为它有助于我们做出决定。感谢您的帮助。 - jflood.net
@jflood.net - HTTP 中很少有绝对的规定(例如,410 Gone 令人想起)。405 表示请求的操作在此刻无法应用于指定的资源。我认为,甚至可以从“DELETE”返回 405,并在响应中包含“DELETE”的允许方法列表。 - D.Shawley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接