例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
当前回答
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服务器从自己的作用域提供的信息:即,是否发现服务在处理请求。
相反,应该使用一种不同的方式将请求的状态告知使用者,以告知实际处理请求的服务。我的建议是通过一个特定的头文件来实现。理想情况下,报头的名称及其内容都遵循一种标准,使使用者可以很容易地处理这些响应。
我们现在看到的是两种范式之间的紧张关系。
在HTTP和REST中,URL标识一个资源,该用户/9资源包括9。因此HTTP应该返回404—未找到。这就是RESTful的定义。之后,你可以PUT user/9,然后当你得到下一次,你得到数据。这就是HTTP和REST的设计方式。
在HTTP级别,如果你不想要404,一个更好的URL会是user?Id =9,那么用户部分将被找到,函数可以进行自己的处理并返回它自己的“未找到”通知。
然而,为了方便指定api,使用user/9格式“更好”。这给我们留下了一个困境:这个请求是通过HTTP发出的,(固执的)正确的HTTP答案是404;但是从API使用者的角度来看,框架可能不能很好地处理404,他们想要200 +一个“not found”有效负载(204对许多框架来说也可能是问题)。
这种将API放在已经定义的协议(HTTP)之上的做法导致了这种紧张。当设计成一个真正的RESTful API时(并且正确地处理404错误),这是没有问题的。
如果您认为user/9应该返回200 +“not found”,那么您使用user作为RPC端点,然后在URL的其余部分编码参数。我认为这是一种糟糕的设计,与RESTful规范相反,并且完全理解我们是如何走到这一步的。
如果你控制了两端,考虑到你的服务器和客户端框架的限制,就做那些有效的事情。
(想想在用户/9上执行HEAD请求的后果——你不能在响应中提供任何内容。200将表明用户/9确实存在,而404将(正确地)表明它不存在。)
看完疑问后,为什么不应该使用404 ?
根据RFC 7231,正确的状态码是204
在上面的回答中,我注意到一个小错误:
1.—资源为:/users
2.- /users/8不是资源,而是:路由参数为8的资源/users,消费者可能注意不到,也不知道区别,但是发布者知道,而且必须知道!所以他必须为消费者返回一个准确的响应。时期。
so:
基于RFC: 404是不正确的,因为找到了资源/用户,但是使用参数8执行的逻辑没有找到任何内容作为响应返回,因此正确的答案是:204
这里的要点是:404甚至没有找到处理内部逻辑的资源
204是a:我找到了资源,逻辑被执行了,但我没有发现任何数据使用你在路由参数中给出的标准,所以我不能返回任何东西给你。对不起,核实你的标准后再打电话给我。
200:好吧,我找到了资源,逻辑被执行(即使当我不被迫返回任何东西)采取这一点,并在你的意愿使用它。
205:(GET响应的最佳选项)我找到了资源,逻辑被执行了,我有一些内容给你,好好使用它,哦,顺便说一下,如果你要在视图中共享这个,请刷新视图以显示它。
希望能有所帮助。
根据w3的帖子,
200好了
请求成功。随响应返回的信息取决于请求中使用的方法
202年接受
请求已接受处理,但处理尚未完成。
204无内容
服务器已经完成了请求,但不需要返回实体主体,并且可能希望返回更新后的元信息。
400错误请求
由于语法错误,服务器无法理解请求。客户不应该在没有修改的情况下重复请求
401年未经授权
请求需要用户身份验证。响应必须包含一个WWW-Authenticate报头字段
404未找到
服务器没有发现任何与Request-URI匹配的内容。没有说明这种情况是暂时的还是永久的
这里有两个问题。一个在标题中,一个在例子中。我认为,这在一定程度上导致了关于哪种反应是合适的争议。
问题标题询问空数据。空数据仍然是数据,但不等于没有数据。因此,这意味着请求一个结果集,即一个列表,可能来自/users。如果一个列表是空的,它仍然是一个列表,因此204(无内容)是最合适的。您刚刚请求了一个用户列表,并得到了一个列表,它只是碰巧没有内容。
相反,所提供的示例询问了一个特定的对象,一个用户/users/9。如果没有找到用户#9,则不返回任何用户对象。您请求一个特定的资源(一个用户对象),但由于没有找到而没有得到它,因此404是合适的。
我认为解决这个问题的方法是,如果您可以在不添加任何条件语句的情况下使用响应,那么使用204,否则使用404。
在我的例子中,我可以迭代一个空列表而不检查它是否有内容,但是我不能在一个空对象上显示用户对象数据而不破坏一些东西或添加一个检查来查看它是否为空。
当然,如果适合您的需要,您可以使用空对象模式返回一个对象,但这是另一个线程的讨论。