例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
当前回答
这样的事情可能是主观的,双方都有一些有趣和各种扎实的论点。然而,(在我看来)为丢失的数据返回404是不正确的。这里有一个简单的描述来说明这一点:
请求:能给我一些数据吗? 资源(API端点):我将在这里为您获取请求[发送潜在数据的响应]
没有问题,找到了端点,找到了表和列,因此查询了DB,并“成功”返回了数据!
现在,无论“成功响应”是否有数据都不重要,您要求“潜在”数据的响应,并且具有“潜在”数据的响应得到了满足。Null,空等是有效的数据。
200只代表我们的请求成功了。我正在请求数据,HTTP/REST没有任何问题,作为数据(尽管为空)返回我的“数据请求”是成功的。
返回一个200,让请求者在每个特定场景下处理空数据!
想想这个例子:
请求:查询用户ID为1234的“违规”表 资源(API端点):返回一个响应,但数据为空
此数据为空是完全有效的。这意味着用户没有违规行为。这是200,因为它是有效的,然后我可以这样做:
你没有违规,吃个蓝莓松饼!
如果你认为这是404,你在说什么?无法发现用户的违规行为?从语法上讲,这是正确的,但在REST世界中,成功或失败是关于请求的,这是不正确的。该用户的“违规”数据可以成功找到,没有违规-一个实数代表有效状态。
(厚颜无耻的注意。)
在你的标题中,你下意识地认为200是正确的回答:
对于有效请求但空数据,正确的REST响应代码是什么?
在选择使用哪种状态码时,抛开主观性和棘手的选择,以下是一些需要考虑的事情:
一致性。如果您使用404表示“无数据”,则在每次响应返回无数据时使用它。 同一个状态不要有多个意思。如果在没有找到资源时返回404(例如API端点不存在等),那么也不要因为没有返回数据而使用它。这只会让应对反应变成一种痛苦。 仔细考虑上下文。什么是“请求”?你说你想达到什么目的?
其他回答
根据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是有意义的。
为了总结或简化,
2xx:可选数据:格式良好的URI: Criteria不是URI的一部分:如果Criteria是可选的,可以在@RequestBody和@RequestParam中指定,应该导致2xx。例如:按名称/状态过滤
标准是URI的一部分:如果标准是强制性的,只能在@PathVariable中指定,那么它应该导致4xx。例如:按唯一id查找。
对于所问的情况: "users/9"将是4xx(可能是404) 但是对于“用户”呢?Name =superman”应该是2xx(可能是204)
令人难过的是,如此简单和明确的东西在这个帖子中变成了“基于意见的”。
HTTP服务器只知道“实体”,这是对任何内容的抽象,可以是静态网页、搜索结果列表、其他实体列表、某物的json描述、媒体文件等等。
每个这样的实体都应该由一个唯一的URL来识别,例如。
/user/9——一个单独的实体:user ID=9 /users——单个实体:所有用户的LIST /media/x.mp3——一个单独的实体:一个名为x.mp3的媒体文件 /search—单个实体:基于查询参数的动态CONTENT
如果服务器通过给定的URL找到一个资源,那么它的内容是什么并不重要——2G的数据、null、{}、[]——只要它存在,它就会是200。但是如果服务器不知道这个实体,它将返回404“not Found”。
One confusion seems to be from developers who think if the application has a handler for a certain path shape, it should not be an error. In the eyes of the HTTP protocol it does not matter what happened in the internals of the server (ie. whether the default router responded or a handler for a specific path shape), as long as there is no matching entity on the server to the requested URL (that requested MP3 file, webpage, user object etc), which would return valid contents (empty or otherwise), it must be 404 (or 410 etc).
另一个令人困惑的地方似乎是“没有数据”和“没有实体”。前者是关于实体的内容,后者是关于实体的存在。
示例1:
No data: /users返回200 OK,正文:[],因为还没有人注册 没有实体:/users返回404,因为没有路径/users
示例2:
No data: /user/9返回返回200 OK,正文:{},因为用户ID=9从未输入他/她的个人数据 没有实体:/user/9返回404,因为没有用户ID=9
示例3:
No data: /search?name=Joe返回200 OK[],因为DB中没有Joe 没有实体:/search?name=Joe返回404,因为没有路径/搜索
如果期望资源存在,但它可能是空的,我认为它可能更容易得到一个200 OK的表示,表明这个东西是空的。
因此,我宁愿让/things返回一个带有{"Items":[]}的200 OK,而不是一个没有任何内容的204,因为这样,一个包含0项的集合可以被视为一个包含一个或多个项目的集合。
我将把204 No Content留给put和delete,在这种情况下,可能真的没有有用的表示。
在/thing/9不存在的情况下,404是合适的。