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

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


当前回答

现有的答案没有详细说明使用路径参数还是查询参数是有区别的。

In case of path parameters, the parameter is part of the resource path. In case of /users/9, the response should be 404 because that resource was not found. /users/9 is the resource, and the result is unary, or an error, it doesn't exist. This is not a monad. In case of query parameters, the parameter is not part of the resource path. In case of /users?id=9, the response should be 204 because the resource /users was found but it could not return any data. The resource /users exists and the result is n-ary, it exists even if it is empty. If id is unique, this is a monad.

使用路径参数还是查询参数取决于用例。我更喜欢将路径参数用于强制的、规范的或标识参数,将查询参数用于可选的、非规范的或属性参数(如分页、排序区域设置等)。在REST API中,我会使用/users/9而不是/users?Id =9,特别是因为可能嵌套获取“子记录”,如/users/9/ SSH -keys/0获取第一个公共SSH密钥或/users/9/address/2获取第三个邮政地址。

我更喜欢使用404。原因如下:

Calls for unary (1 result) and n-ary (n results) methods should not vary for no good reason. I like to have the same response codes if possible. The number of expected results is of course a difference, say, you expect the body to be an object (unary) or an array of objects (n-ary). For n-ary, I would return an array, and in case there are not results, I would not return no set (no document), I would return an empty set (empty document, like empty array in JSON or empty element in XML). That is, it's still 200 but with zero records. There's no reason to put this information on the wire other than in the body. 204 is like a void method. I would not use it for GET, only for POST, PUT, and DELETE. I make an exception in case of GET where the identifiers are query parameters not path parameters. Not finding the record is like NoSuchElementException, ArrayIndexOutOfBoundsException or something like that, caused by the client using an id that doesn't exist, so, it's a client error. From a code perspective, getting 204 means an additional branch in the code that could be avoided. It complicates client code, and in some cases it also complicates server code (depending on whether you use entity/model monads or plain entities/models; and I strongly recommend staying away from entity/model monads, it can lead to nasty bugs where because of the monad you think an operation is successful and return 200 or 204 when you should actually have returned something else). Client code is easier to write and understand if 2xx means the server did what the client requested, and 4xx means the server didn't do what the client requested and it's the client's fault. Not giving the client the record that the client requested by id is the client's fault, because the client requested an id that doesn't exist.

最后一点:一致性

GET /用户/ 9 PUT /users/9和DELETE /users/9

PUT /users/9和DELETE /users/9已经必须在成功更新或删除的情况下返回204。如果用户9不存在,它们应该返回什么?根据所使用的HTTP方法将相同的情况显示为不同的状态代码是没有意义的。

Besides, not a normative, but a cultural reason: If 204 is used for GET /users/9 next thing that will happen in the project is that somebody thinks returning 204 is good for n-ary methods. And that complicates client code, because instead of just checking for 2xx and then decoding the body, the client now has to specifically check for 204 and in that case skip decoding the body. Bud what does the client do instead? Create an empty array? Why not have that on the wire, then? If the client creates the empty array, 204 is a form of stupid compression. If the client uses null instead, a whole different can of worms is opened.

其他回答

为了总结或简化,

2xx:可选数据:格式良好的URI: Criteria不是URI的一部分:如果Criteria是可选的,可以在@RequestBody和@RequestParam中指定,应该导致2xx。例如:按名称/状态过滤

标准是URI的一部分:如果标准是强制性的,只能在@PathVariable中指定,那么它应该导致4xx。例如:按唯一id查找。

对于所问的情况: "users/9"将是4xx(可能是404) 但是对于“用户”呢?Name =superman”应该是2xx(可能是204)

Twitter使用404,并带有类似“找不到数据”的自定义错误消息。

裁判:https://developer.twitter.com/en/docs/basics/response-codes.html

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

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.

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