【发布时间】:2017-10-24 02:28:46
【问题描述】:
如果我有如下所示的 REST 资源:
GET http://www.example.com/customers/{customerId}/orders
如果提供的 customerId 不存在,我的服务器应该返回 404(未找到)还是 400(错误请求)?
【问题讨论】:
标签: rest http-status-code-404 http-status-codes
如果我有如下所示的 REST 资源:
GET http://www.example.com/customers/{customerId}/orders
如果提供的 customerId 不存在,我的服务器应该返回 404(未找到)还是 400(错误请求)?
【问题讨论】:
标签: rest http-status-code-404 http-status-codes
我认为应该是 404 状态,因为请求是有效的,但是没有找到 customerID。
【讨论】:
我会说在这种情况下你应该返回404 Not Found。
为了详细说明这个问题,我对本例中的规范解释如下:
400 Bad Request 用于应用程序成功接收请求,并且应用程序确定请求有问题的情况:端点不存在,或者请求参数的格式或性质/variables 在某些方面不正确/格式错误,导致请求无效。
这在 @Trevor Conn 的示例中,其中请求中的 customerID 的格式无效(太长、太短、无效字符等),并且由于无法尝试查找或操作到错误。
200 系列响应(@Trevor Conn 也提到过)表明针对有效实体或主题的请求已成功处理。
204 No Content应该用于发现主题或执行操作,并且请求的真实有效的输出或结果为“Nothing”的情况。
据我了解,这会做一些事情:
204 No Content 的端点,它会向浏览器指示请求成功,但实际上不会导航到任何地方(视口和当前 URI,将保持不变)。在您的情况下,404 Not Found 将是对有效端点请求的正确响应,具有正确格式的 customerID,不会解析为客户。
往兔子洞里走一点……
您还可以跟踪哪些有效的customerIDs 已被删除/存档,如果它们曾经存在,则回复410 Gone,如果客户因法律要求而被删除,则回复451 Unavailable For Legal Reasons。
另外值得注意的是,如果您使用 OOP 语言工作,您可能处于将端点/操作视为“方法”的生态系统中。
如果你真的想走 HTTP 响应代码的兔子洞,值得注意的是 400 Bad Request 在这种情况下处理丢失的“方法”。这与405 Method Not Allowed 不同,Method Not Allowed 中的“方法”指的是 HTTP 方法(GET/POST/PUT/DELETE)。 405 应该使用并且仅在客户端尝试对不支持该方法的端点使用这些方法之一的情况下使用。
这方面的一个例子是使用:
DELETE http://www.example.com/customers/{customerId}/orders
正确的用法应该是:
DELETE http://www.example.com/customers/{customerId}/orders/{orderID}
更进一步的兔子洞:“不允许”严格指该方法是否被实现,如果用户缺乏执行其他实现的 HTTP 方法的权限,正确的响应将是403 Forbidden,或者401 Unauthorized,如果客户端的权限由于客户端还没有经过身份验证而无法确定。
更多兔子洞...
501 Not Implemented 是 HTTP 方法故障的服务器指示器(因为它自己的服务器,无论是 Nginx、Apache 还是任何其他服务器)在基础级别上不支持 HTTP 请求方法。
IE:
EXPELLIARMUS http://www.example.com/customers/{customerId}
205 Reset Content 与204 相似,因为它指示请求成功,以及一个真正的空响应,除了它指示客户端就地重置其文档视图(204 确实根本不会触发任何动作)。
【讨论】:
有几种不同的方法可以解决这个问题。
如果您正在检查 {customerId} 并发现它完全是伪造的,那么 400 - Bad Request 是有意义的。
但是,如果 {customerId} 的格式和类型有效,但它不存在,那么我会建议 204 - 无内容。在我看来,这种情况不是正确的 404,因为找到了操作。
假设用户提供了一个有效的路径,即使customerId 123456 不存在,那么调用执行成功并且没有返回任何数据。因此 204 无内容。
200 范围内的状态也被视为“成功”状态,因此您可以验证您的调用对于格式正确的 {customerId} 是否成功。然而,确定该 ID 是否有效可能是另一个服务的责任。
【讨论】: