例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
当前回答
Twitter使用404,并带有类似“找不到数据”的自定义错误消息。
裁判:https://developer.twitter.com/en/docs/basics/response-codes.html
其他回答
TL;DR:使用404
请看这个博客。这解释得很好。
博客对204的评论总结如下:
204 No Content作为浏览器的响应代码并不是特别有用(尽管根据HTTP规范,浏览器需要将其理解为“不要更改视图”的响应代码)。 然而,No Content对于ajax web服务非常有用,它可能想要表示成功而不需要返回任何东西。(特别是在DELETE或post这样不需要反馈的情况下)。
因此,您的问题的答案是在您的情况下使用404。204是一个专门的响应代码,您不应该经常将其返回给浏览器以响应GET。
其他响应代码甚至比204和404更不合适:
200 should be returned with the body of whatever you successfully fetched. Not appropriate when the entity you're fetching doesn't exist. 202 is used when the server has begun work on an object but the object isn't fully ready yet. Certainly not the case here. You haven't begun, nor will you begin, construction of user 9 in response to a GET request. That breaks all sorts of rules. 400 is used in response to a poorly formatted HTTP request (for instance malformed http headers, incorrectly ordered segments, etc). This will almost certainly be handled by whatever framework you're using. You shouldn't have to deal with this unless you're writing your own server from scratch. Edit: Newer RFCs now allow for 400 to be used for semantically invalid requests.
维基百科对HTTP状态码的描述尤其有用。 您也可以在www.w3.org上看到HTTP/1.1 RFC2616文档中的定义
我得说,两者都不太合适。 正如@anneb所说的,我也认为部分问题来自于使用HTTP响应代码来传输与RESTful服务相关的状态。REST服务关于其自身处理的任何信息都应该通过特定于REST的代码来传输。
1
我认为,如果HTTP服务器发现任何服务已经准备好响应它发送的请求,它不应该响应HTTP 404——最后,服务器找到了一些东西——除非处理请求的服务明确地告诉它。
让我们暂时假设以下URL: http://example.com/service/return/test。
Case A is that the server is “simply looking for the file on the file system“. If it is not present, 404 is correct. The same is true, if it asks some kind of service to deliver exactly this file and that service tells it that nothing of that name exists. In case B, the server does not work with “real” files but actually the request is processed by some other service – e.g. some kind of templating system. Here, the server cannot make any claim about the existence of the resource as it knows nothing about it (unless told by the service handling it).
如果没有来自服务的任何响应显式地要求不同的行为,HTTP服务器只能说3件事:
503,如果处理请求的服务没有运行或响应; 否则,作为HTTP服务器实际上可以满足请求-不管服务稍后会说什么; 400或404表示没有这样的服务(相对于“存在但脱机”),并且没有找到其他服务。
2
回到手头的问题:我认为最干净的方法是除了前面提到的以外,不使用任何HTTP响应代码。如果服务存在并响应,HTTP代码应该是200。 响应应该在一个单独的报头中包含服务返回的状态——在这里,服务可以说
REST:EMPTY,例如,如果它被要求搜索某物,而该研究返回为空; REST:NOT FOUND,如果它被特别地请求某事物,“ID-like”-是一个文件名或一个ID的资源或条目号24等-并且没有找到特定的资源(通常,一个特定的资源被请求但没有找到); REST:如果发送的请求的任何部分不被服务识别,则为无效。
(注意,我故意用“REST:”作为前缀,以标记这样一个事实,即虽然它们可能具有与HTTP响应代码相同的值或措辞,但它们是完全不同的东西)
3
让我们回到上面的URL并检查用例B,其中服务指示HTTP服务器它不处理这个请求本身,而是将它传递给服务。HTTP只提供SERVICE返回的内容,它不知道任何关于返回/测试部分的内容,因为这是由SERVICE处理的。如果该服务正在运行,HTTP应该返回200,因为它确实找到了处理请求的东西。
SERVICE返回的状态(如上所述,希望在单独的头文件中看到)取决于实际期望的操作:
if return/test asks for a specific resource: if it exists, return it with a status of REST:FOUND; if that resource does not exist, return REST:NOT FOUND; this could be extended to return REST:GONE if we know it once existed and will not return, and REST:MOVED if we know it has gone hollywood if return/test is considered a search or filter-like operation: if the result set is empty, return an empty set in the type requested and a status of REST:EMPTY; a set of results in the type requested and a status of REST:SUCCESS if return/test is not an operation recogized by SERVICE: return REST:ERROR if it is completely wrong (e.g. a typo like retrun/test), or REST:NOT IMPLEMENTED in case it is planned for later.
4
这种区别比把两种不同的东西混在一起要清楚得多。它还将使调试更容易,处理也只是稍微复杂一些。
如果返回一个HTTP 404,服务器会告诉我,“我不知道你在说什么”。虽然请求的REST部分可能完全没问题,但我在所有错误的地方都在寻找par'Mach。 另一方面,HTTP 200和REST:ERR告诉我,我得到了服务,但在对服务的请求中做了错误的事情。 从HTTP 200和REST:EMPTY,我知道我没有做错什么-正确的服务器,服务器找到了服务,正确的请求到服务-但搜索结果是空的。
总结
这个问题和讨论源于这样一个事实:HTTP响应码被用来表示由HTTP提供结果的服务的状态,或者用来表示不在HTTP服务器本身范围内的事物。 由于这种差异,这个问题无法回答,所有的意见都要经过大量的讨论。
由服务而不是HTTP服务器处理的请求的状态真的不应该(RFC 6919)由HTTP响应代码给出。HTTP代码应该(RFC 2119)只包含HTTP服务器从自己的作用域提供的信息:即,是否发现服务在处理请求。
相反,应该使用一种不同的方式将请求的状态告知使用者,以告知实际处理请求的服务。我的建议是通过一个特定的头文件来实现。理想情况下,报头的名称及其内容都遵循一种标准,使使用者可以很容易地处理这些响应。
正如许多人所说的,404会误导客户端,如果请求uri不存在,或者请求的uri不能获取请求的资源,它不允许客户端进行区分。
200状态被期望包含资源数据——所以它不是正确的选择。 204状态意味着完全不同的东西,不应该用作GET请求的响应。
由于这样或那样的原因,所有其他现有状态都不适用。
我看到这个话题在很多地方被反复讨论。对我来说,很明显,要消除围绕这个话题的困惑,就需要一个专门的成功状态。比如“209 -没有资源显示”。
这将是一个2xx状态,因为找不到ID不应该被认为是客户端错误(如果客户端知道服务器DB中的所有内容,它们就不需要向服务器询问任何事情,不是吗?)这个专用状态将解决所有与使用其他状态争论的问题。
唯一的问题是:我如何让RFC接受这个标准?
根据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请求,结果为空。(例如:一个没有特定过滤器结果的列表)
TL; diana:
如果在/users/9上没有找到用户,则应该返回404。 如果在/users中没有找到用户?如果Id =9,则应该返回204。
长版:
在回顾了我自己对这些状态代码的使用和本文中的示例之后,我不得不说,如果在/users/9的url上没有找到用户#9,404是适当的响应。
今天在我的系统中,我们的Application Insights日志中充满了数百条记录的404错误,这使我们的日志变得混乱,因为我们决定在/users/9没有相关数据时返回404错误。然而,这并不意味着我们在设置响应时的方法是不正确的,相反,我认为这意味着我们在设置路由时的方法是不正确的。
如果您希望端点获得大量流量,并且担心记录太多404错误,那么您应该更改路由以符合您想要的状态码,而不是强制使用不适当的状态码。
我们已经决定对我们的代码做2个更改:
通过expect /users改变我们的工作路线?id = 9 将我们的错误代码更改为204,这样404就不会填满我们的AI日志。
最后,API的架构师需要了解他们的API将如何被使用,以及哪种路由将适合于该用例。
我相信在/users/9的情况下,您请求的资源是用户本身,用户#9;您要求服务器响应一个标识为“9”的对象,该对象恰好存在于包含单词“user”的路径中。如果没有找到该对象,则应该得到404。
但是,如果调用/users?id=9,我觉得你所请求的资源是用户控制器,同时也提供了更多的专一性,这样它就不会返回所有用户的完整列表。您要求服务器响应一个可以通过查询字符串中定义的ID号识别的特定用户。因此,如果没有找到数据,204对我来说是有意义的,因为即使没有找到数据,控制器也是。
查询字符串方法还完成了一些我认为不仅有助于API开发人员,而且有助于客户端开发人员(特别是初级开发人员或继承这段代码或调用它的代码的未来开发人员):
It becomes immediately clear to anyone involved that 9 is an ID, not some arbitrary number. This point may seem moot in such a basic example, but consider a system that uses GUIDs as row ID's or allows you to get data by a person's name, or even a system that is returning info for specific ZIP/postal codes instead of row ID's. It would be useful for all developers involved if, at a glance, they knew whether that identifying parameter was a first, last, full name, or a ZIP/postal code instead of an ID.