当成功的 REST 查询给出 0 个结果时,404 http 代码是否合适?

Is a 404 http code appropriate when a successful REST query gives 0 results?

本周我们在工作中就正确使用 HTTP 错误代码 404 进行了一些激烈的争论。我觉得在这种情况下使用不当,他们坚持 "this is how it is everywhere"。

场景如下: 我们有一个带有静态 URI 的 REST API 端点,如“https://server.domain.com/restapi/getnode”,它在 POST 操作期间接受 json 主体以查看服务器是否存在于数据库中。每个查询允许 1 个服务器。
它的设计方式是,如果服务器存在,它 return 的 http 代码 200 消息正文是数据库中服务器的详细信息。如果它不存在,那么他们 return 带有消息 "server x is not found in database y" 的 404 代码。

我觉得这是不正确的,因为根据 W3C 的标准,4xx 代码用于与客户端相关的问题,而 404 则专门针对服务器无法提供该特定 URI 的情况。此外,这并不是真正的错误,我们不仅希望偶尔出现 negative/empty 响应作为正常业务的一部分,而且预计大多数调用都会出现这种情况。

他们对此的回应是,根据 AWS REST Standards and ServiceNow REST Standards 等来源,404 是合适的,因为查询没有找到服务器,因此找不到资源(对此我觉得他们误解了术语 "resource").

那么,谁是正确的?或者这比我想象的更像是一个灰色地带?

这是一场永无休止的辩论,没有任何有用的结果。例如,请参阅 How to design RESTful search/filtering?, Do web applications use HTTP as a transport layer, or do they count as an integral part of the HTTP server?(免责声明:我的问题),以及 Stack Exchange 网络上的数千个其他问题和数以千计的博客,例如 "which status code to pick for REST scenario XYZ"。

您将 POST 用于具有 GET 语义的请求这一事实意味着您尚未正确应用 REST。 POST是用来创建资源的,不是用来找现有资源的。如果您有 "servers" 个资源集合,那么您正在处理 "server" 个资源。

如果你想要一个 "find-server" 端点,并且你想使用 POST 到 "create" 一个 "find-server resource result",然后你可以向它发出 GET 请求为了获得您的搜索结果,您是一个试图将应用程序硬塞进不适合问题域的设计理念的受虐狂。

所以要务实一点。端点存在吗?是的,所以 404 不适用。 Return 200(资源存在,请求正确),正文表示没有找到结果,或者 204("no content")没有正文。

这里规范的相关部分是Client Error 4xx

Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.

User agents SHOULD display any included representation to the user.

换句话说,状态代码是元数据,它向通用组件指示响应的有效负载是对错误的解释,而不是资源的表示。

如果您实际上正在做的是返回资源的表示,此时它是一个空列表,那么您应该使用成功代码,而不是客户端错误代码。

例如,如果我们有一个资源列出了宣誓就任美国总统办公室的女性,那么截至 2019-09-25,该资源的表达式将是一个空列表。所以标准的 HTTP 响应看起来像

200 OK
Content-Type: application/json

[]

另一方面,这个回复说的是完全不同的东西

404 Not Found
Content-Type: application/json

[]

这里说的是请求的资源没有当前的表示,问题的解释的表示是一个空列表,所以请显示一个空列表给用户,让他们知道该怎么做。