例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
例如,您为用户/9运行一个GET请求,但没有id为#9的用户。 哪个是最佳响应码?
200好了 202年接受 204无内容 400错误请求 404未找到
当前回答
我们现在看到的是两种范式之间的紧张关系。
在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响应的最佳选项)我找到了资源,逻辑被执行了,我有一些内容给你,好好使用它,哦,顺便说一下,如果你要在视图中共享这个,请刷新视图以显示它。
希望能有所帮助。
为了总结或简化,
2xx:可选数据:格式良好的URI: Criteria不是URI的一部分:如果Criteria是可选的,可以在@RequestBody和@RequestParam中指定,应该导致2xx。例如:按名称/状态过滤
标准是URI的一部分:如果标准是强制性的,只能在@PathVariable中指定,那么它应该导致4xx。例如:按唯一id查找。
对于所问的情况: "users/9"将是4xx(可能是404) 但是对于“用户”呢?Name =superman”应该是2xx(可能是204)
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.
Twitter使用404,并带有类似“找不到数据”的自定义错误消息。
裁判:https://developer.twitter.com/en/docs/basics/response-codes.html
这里有两个问题。一个在标题中,一个在例子中。我认为,这在一定程度上导致了关于哪种反应是合适的争议。
问题标题询问空数据。空数据仍然是数据,但不等于没有数据。因此,这意味着请求一个结果集,即一个列表,可能来自/users。如果一个列表是空的,它仍然是一个列表,因此204(无内容)是最合适的。您刚刚请求了一个用户列表,并得到了一个列表,它只是碰巧没有内容。
相反,所提供的示例询问了一个特定的对象,一个用户/users/9。如果没有找到用户#9,则不返回任何用户对象。您请求一个特定的资源(一个用户对象),但由于没有找到而没有得到它,因此404是合适的。
我认为解决这个问题的方法是,如果您可以在不添加任何条件语句的情况下使用响应,那么使用204,否则使用404。
在我的例子中,我可以迭代一个空列表而不检查它是否有内容,但是我不能在一个空对象上显示用户对象数据而不破坏一些东西或添加一个检查来查看它是否为空。
当然,如果适合您的需要,您可以使用空对象模式返回一个对象,但这是另一个线程的讨论。