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

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


当前回答

根据微软:控制器动作返回类型在ASP。NET Core web API,向下滚动几乎到底部,你会发现下面关于404的简介,与数据库中没有的对象有关。在这里,他们建议404适用于空数据。

其他回答

Just an addition from a developer that struggled many times with this situation. As you might have noticed it is always a discussion whether you return a 404 or 200 or 204 when a particular resource does not exist. The discussion above shows that this topic is pretty confusing and opinion based ( while there is a http-status-code standard existing ). I personally recommend, as it was not mentioned yet I guess, no matter how you decide DOCUMENT IT IN YOUR API-DEFINITION. Of course a client-side developer has in mind when he/she uses your particular "REST"- api to use his/her knowledge about Rest and expects that your api works this way. I guess you see the trap. Therefor I use a readme where I explicitly define in which cases I use which status code. This doesn't mean that I use some random definion. I always try to use the standard but to avoid such cases I document my usage. The client might think you are wrong in some specific cases but as it is documented, there is no need for additional discussions what saves time for you and the developer.

One sentence to the Ops question: 404 is a code that always comes in my mind when I think back about starting to develop backend-applications and I configured something wrong in my controller-route so that my Controller method is not called. With that in mind, I think if the request does reach your code in a Controller method, the client did a valid request and the request endpoint was found. So this is an indication not to use 404. If the db query returns not found, I return 200 but with an empty body.

这个话题中的答案(在撰写本文时已经有26个)完美地说明了开发人员理解他们正在使用的构造的语义是多么重要。

如果不理解这一点,那么响应状态代码是响应的属性而不是其他属性就不明显了。这些代码存在于响应的上下文中,它们在此上下文中之外的含义是未定义的。

响应本身就是请求的结果。请求对资源进行操作。资源、请求、响应和状态代码是HTTP的结构,就HTTP而言:

HTTP提供了与资源(第2节)交互的统一接口,无论其类型、性质或实现如何,通过操作和传输表示(第3节)。

换句话说,响应状态码的范围受到一个接口的限制,该接口只关心一些目标资源,并处理用于与这些资源交互的消息。服务器应用程序逻辑超出了范围,您使用的数据也不重要。

当使用HTTP时,它总是与资源一起使用。资源被以太转移或操纵。在任何情况下,除非我们在量子世界中,资源要么存在要么不存在,不存在第三种状态。

如果发出HTTP请求来获取(传输)资源的表示(如本问题中所示),而资源不存在,则响应结果应该显示一个带有相应404代码的失败。目标-获取表示-没有达到,资源没有找到。在HTTP上下文中不应该有对结果的其他解释。

RFC 7231超文本传输协议(HTTP/1.1):语义和内容,在这里多次提到,但主要是作为状态码描述的参考。我强烈建议通读整个文档,而不仅仅是第6节,以便更好地理解HTTP接口及其组件的作用域和语义。

在这个场景中,Ruby on Rails响应404 Not Found。

客户端请求不存在的资源。因此,404 Not Found更合适。


Edit

我发现,在这种情况下,许多开发人员不喜欢找不到404。

如果您不想使用404,我认为,您可以使用以下两个响应代码中的任何一个:

200好了 204无内容

如果你使用200 OK:响应体应该是空json:[]或{}

如果你使用204 OK:响应体应该为空。

使用公共枚举对响应内容进行编码,以允许客户端打开它并相应地派生逻辑。我不知道你的客户如何区分“数据未找到”404和“网络资源未找到”404之间的区别?您不希望有人浏览到userZ/9,并让客户端怀疑请求是否有效,但没有返回数据。

我强烈反对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.