例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?

200好了 202年接受 204无内容 400错误请求 404未找到


当前回答

这里有两个问题。一个在标题中,一个在例子中。我认为,这在一定程度上导致了关于哪种反应是合适的争议。

问题标题询问空数据。空数据仍然是数据,但不等于没有数据。因此,这意味着请求一个结果集,即一个列表,可能来自/users。如果一个列表是空的,它仍然是一个列表,因此204(无内容)是最合适的。您刚刚请求了一个用户列表,并得到了一个列表,它只是碰巧没有内容。

相反,所提供的示例询问了一个特定的对象,一个用户/users/9。如果没有找到用户#9,则不返回任何用户对象。您请求一个特定的资源(一个用户对象),但由于没有找到而没有得到它,因此404是合适的。

我认为解决这个问题的方法是,如果您可以在不添加任何条件语句的情况下使用响应,那么使用204,否则使用404。

在我的例子中,我可以迭代一个空列表而不检查它是否有内容,但是我不能在一个空对象上显示用户对象数据而不破坏一些东西或添加一个检查来查看它是否为空。

当然,如果适合您的需要,您可以使用空对象模式返回一个对象,但这是另一个线程的讨论。

其他回答

我强烈反对404,而支持204或200的空数据。或者至少应该使用带有404的响应实体。

请求被接收并被正确处理——它确实触发了服务器上的应用程序代码,客户机可能没有犯任何错误,因此整个客户机错误代码(4xx)类可能不合适。

更重要的是,404的发生有很多技术原因。例如,应用程序在服务器上被暂时停用或卸载,代理连接问题等等。

当然,这种情况下存在5xx错误类,但实际上,受影响的中间件组件通常无法知道错误在它们这一边,然后只是假设错误在客户端,然后响应404而不是500/503。

因此,仅根据状态代码,客户端无法区分404(表示“您正在寻找的东西不存在”)和404(表示“有严重错误,请将此错误报告给运维团队”)。

This can be fatal: Imagine an accounting service in your company that lists all the employees that are due to an annual bonus. Unfortunately, the one time when it is called it returns a 404. Does that mean that no-one is due for a bonus, or that the application is currently down for a new deployment and the 404 is actually coming from the tomcat that it's supposed to be installed into, instead of from the application itself? These two scenarios yield the same status code, but they are fundamentally different in their meaning.

对于需要知道所请求的资源不存在而不是暂时不可访问的应用程序来说,没有响应实体的404几乎是行不通的。

此外,许多客户端框架通过抛出异常来响应404,而不询问进一步的问题。这迫使客户端开发人员捕获异常,对其进行评估,然后基于此决定是否将其记录为由监视组件捕获的错误,或者是否忽略它。这对我来说也不太好。

The advantage of 404 over 204 is that it can return a response entity that may contain some information about why the requested resource was not found. But if that really is relevant, then one may also consider using a 200 OK response and design the system in a way that allows for error responses in the payload data. Alternatively, one could use the payload of the 404 response to return structured information to the caller. If he receives e.g. a html page instead of XML or JSON that he can parse, then that is a good indicator that something technical went wrong instead of a "no result" reply that may be valid from the caller's point of view. Or one could use a HTTP response header for that.

尽管如此,我还是更喜欢204或200的空白回复。这样,请求的技术执行状态就与请求的逻辑结果分开了。2xx的意思是“技术执行ok,这就是结果,处理它”。

我认为在大多数情况下,应该让客户来决定一个空的结果是否可以接受。通过返回404而不返回响应实体(尽管技术执行正确),客户端可能决定将根本不是错误的情况视为错误。

Another perspective: From an operations point of view a 404 may be problematic. Since it can indicate a connectivity/middleware problem rather than a valid service response, i would not want a fluctuating number of "valid" 404s in my metrics/dashboards that might conceal genuine technical issues (e.g. a misconfigured proxy somewhere in the request routing) that should be investigated and fixed. This is further excarbated by some APIs even using 404 instead of 401/403 (e.g. gitlab does such a thing), to conceal the information that the request URI would have been valid but the request lacked authorization to access it. In this case too a 404 should be treated as a technical error and not as a valid "resource not found" result.

Edit: Wow, this has caused a lot of controversy. Here is another argument against 404: Strictly from a HTTP spec (RFC7231) point of view, 404 does not even mean that a resource does not exist. It only means that the server has no current representation of the requested resource available, and this even may be only temporary. So strictly by HTTP spec, 404 is inherently unreliable regarding the nonexistence of a requested thing. If you want to communicate that the requested thing positively does not exist, do not use 404.

204号更合适。特别是当你有一个警报系统来确保你的网站是安全的,404在这种情况下会引起混乱,因为你不知道一些404警报是后端错误或正常的请求,但响应为空。

根据RFC7231 -第59页(https://www.rfc-editor.org/rfc/rfc7231#page-59) 404状态码响应的定义是:

6.5.4. 404 Not Found The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent; the 410 (Gone) status code is preferred over 404 if the origin server knows, presumably through some configurable means, that the condition is likely to be permanent. A 404 response is cacheable by default; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [RFC7234]).

而引起质疑的主要是上述语境中对资源的定义。 根据同一个RFC(7231), resource的定义是:

Resources: The target of an HTTP request is called a "resource". HTTP does not limit the nature of a resource; it merely defines an interface that might be used to interact with resources. Each resource is identified by a Uniform Resource Identifier (URI), as described in Section 2.7 of [RFC7230]. When a client constructs an HTTP/1.1 request message, it sends the target URI in one of various forms, as defined in (Section 5.3 of [RFC7230]). When a request is received, the server reconstructs an effective request URI for the target resource (Section 5.5 of [RFC7230]). One design goal of HTTP is to separate resource identification from request semantics, which is made possible by vesting the request semantics in the request method (Section 4) and a few request-modifying header fields (Section 5). If there is a conflict between the method semantics and any semantic implied by the URI itself, as described in Section 4.2.1, the method semantics take precedence.

所以在我的理解中,404状态代码不应该用于成功的GET请求,结果为空。(例如:一个没有特定过滤器结果的列表)

根据w3,我相信以下几点:

2xx:

这类状态代码表示成功接收、理解并接受了客户机的请求。

4xx:

4xx类状态代码用于客户端似乎出现错误的情况。

如果客户端请求/users,并且它有用户要列出,响应代码将是200 OK(客户端请求有效)。

如果客户端请求/users并且没有数据,响应代码仍然是200 OK。 被请求的实体/资源是一个用户列表,列表存在,只是其中没有任何用户(如果给出空响应,可以使用204 No Content,尽管我认为空列表[]会更好)。 客户端请求是有效的,资源也确实存在,因此4xx响应代码在这里没有意义。

另一方面,如果客户端请求/users/9,而该用户不存在,那么客户端就犯了一个错误,请求了一个不存在的资源,一个用户。在这种情况下,回答404 Not Found是有意义的。

在以前的项目中,我使用了404。如果没有用户9,则没有找到对象。因此404 Not Found是合适的。

如果对象存在,但没有数据,则为204 no Content。我认为在你的例子中,这个物体并不存在。