什么是适当的REST响应代码的有效请求,但空的数据?

例如,您为users/9运行GET请求,但没有用户ID为9。 哪个是最好的响应码?

  • 200好
  • 202接受
  • 204无内容
  • 400错误的请求
  • 404没有find

TL; DR:使用404

看这个博客 。 它解释得很好。

博客对204的评论总结:

  1. 204 No Content作为浏览器的响应代码并不是非常有用(尽pipe根据HTTP规范,浏览器确实需要将其理解为“不改变视图”的响应代码)。
  2. 然而, 204 No Content 非常有用的Ajax Web服务,可能要表明成功,而不必返回的东西。 (尤其是在DELETEPOST不需要反馈的情况下)。

因此,对你的问题的答案是在你的情况下使用404204是一个专门的响应代码,您不应该经常返回到浏览器响应GET

其他响应代码甚至比204404更合适。

  1. 200应该返回与您成功提取的任何内容。 当您正在提取的实体不存在时不适用。
  2. 当服务器已经开始在一个对象上工作,但该对象还没有完全准备好时,使用202 。 当然不是这里的情况。 您还没有开始,也不会开始构build用户9来响应GET请求。 这打破了各种规则。
  3. 400用于响应格式错误的HTTP请求(例如格式不正确的http头,错误sorting的段等)。 这几乎肯定会被你使用的任何框架处理。 除非你从头开始编写自己的服务器,否则你不应该处理这个问题。 编辑 : 较新的RFC现在允许400用于语义无效的请求。

维基百科对HTTP状态代码的描述特别有用。 您也可以在www.w3.org上查看HTTP / 1.1 RFC2616文档中的定义

我强烈反对404支持204或200个空数据。

这个请求被接收并且被正确地处理 – 它确实触发了服务器上的应用程序代码,因此不能真正地说这是一个客户端错误,因此整个客户端错误代码(4xx)是不合适的。

更重要的是,404可能会出于多种技术原因。 例如,应用程序暂时停用或卸载在服务器上,代理连接问题等等。 因此,客户端无法区分404表示“空结果集”和404表示“服务无法find,稍后再试”的404。

这可能是致命的:想象一下贵公司的一个会计服务,列出所有因年度奖金而发生的员工。 不幸的是,有一次它被称为它会返回一个404。这是否意味着没有人应该得到奖金,或者应用程序目前正在进行新的部署?

– >对于关心数据质量的应用程序来说,404几乎是不可行的。

此外,许多客户端框架通过抛出一个exception来回应404,而不再提出任何问题。 这会强制客户端开发人员捕获该exception,对其进行评估,然后根据是否将其logging为由监视组件拾取的错误或是否忽略它。 这对我来说也不是很好。

与204相比,404的唯一优点是它可以返回一个响应实体,该响应实体可能包含一些关于为什么找不到请求的资源的信息。 但是,如果这真的是相关的,那么也可以考虑使用200 OK响应,并以允许有效载荷数据中的错误响应的方式来devise该系统。 或者,可以使用404响应的有效载荷将结构化信息返回给调用者。 如果他收到一个html页面,而不是XML或JSON,他可以parsing,这是一个很好的指标,技术出了问题,而不是从调用者的angular度来看可能是有效的“没有结果”的答复。 或者可以使用一个HTTP响应头。

尽pipe如此,我仍然宁愿204或200空回应。 这样,请求的技术执行状态与请求的逻辑结果是分开的。 2xx意味着“技术执行好,这是结果,处理它”。

我认为在大多数情况下,应由客户决定是否可以接受空的结果。 尽pipe有正确的技术执行,客户可以决定返回404,将案例视为没有错误的错误。

另一个快速的比喻:如果SQL查询没有返回任何结果,则返回“404找不到结果”就像抛出DatabaseConnectionException。 它可以完成工作,但有很多可能的技术原因,抛出同样的例外,然后将被误认为有效的结果。

在以前的项目中,我使用了404。如果没有用户9,则找不到对象。 因此404 Not Found是合适的。

对于存在的对象,但没有数据,则不适用。 我认为在你的情况下,对象不存在,但。

如果预期资源存在,但可能是空的,那么我认为只要得到一个表示该事物为空的表示就可以更容易。

所以我宁愿有/事情返回一个200 OK与{“项目”:[]}比没有什么的204,因为这样一个集合与0项目可以被视为与一个集合相同或更多的项目在里面。

我只是留下PUT和DELETE的204无内容,在那里可能是真的没有有用的表示。

在/ thing / 9确实不存在的情况下,404是合适的。

根据w3的post,

200好

请求已成功。 与响应一起返回的信息取决于请求中使用的方法

202接受

该请求已被接受处理,但处理尚未完成。

204无内容

服务器已经完成了请求,但不需要返回实体主体,并且可能想要返回更新后的元信息。

400错误的请求

由于格式错误,服务器无法理解请求。 客户端不应该不加修改地重复请求

401未经授权

该请求需要用户authentication。 响应必须包含一个WWW-Authenticate头域

404没有find

服务器没有find任何匹配的请求的URI。 没有迹象表明病情是暂时的还是永久性的

总结或简化,

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

4xx:期望的数据:不正确的URI:标准是URI的一部分:如果标准是必须的,只能在@PathVariable中指定,那么它应该导致4xx。 例如:通过唯一的ID查找。

因此对于被问到的情况:“users / 9”将是4xx(可能是404)但是对于“users?name = superman”应该是2xx(可能是204)

有两个问题要问。 一个在标题中,一个在例子中。 我认为这在一定程度上导致了关于哪个回应是适当的争议的数量。

问题标题问空数据。 空的数据仍然是数据,但不是没有数据。 所以这build议请求一个结果集,即一个列表,也许来自/users 。 如果列表是空的,它仍然是一个列表,因此204(无内容)是最合适的。 你刚才问了一个用户列表,并提供了一个,它只是恰好没有内容。

所提供的例子是问一个特定的对象,一个用户, /users/9 。 如果没有find用户#9,则不返回用户对象。 你问了一个特定的资源(一个用户对象),并没有给它,因为它没有被发现,所以404是适当的。

我认为解决这个问题的方法是,如果你可以按照你期望的方式使用响应而不添加任何条件语句,那么使用204,否则使用404。

在我的例子中,我可以迭代一个空列表,而不检查它是否有内容,但是我不能在空对象上显示用户对象数据而不破坏某些东西,或者添加一个检查来查看它是否为空。

你当然可以使用空对象模式返回一个对象,如果这符合你的需要,但这是另一个线程的讨论。

使用一个通用枚举对响应内容进行编码,允许客户端开启并相应地分配逻辑。 我不知道你的客户如何区分“未find数据”404和“未findnetworking资源”404之间的区别? 你不想让某人浏览到用户Z / 9,并让客户想知道请求是否有效,但是没有返回数据。

为什么不使用410? 它build议所请求的资源不再存在,并且客户端将永远不会请求这个资源,在你的情况下是users/9

你可以在这里find关于410的更多细节: https : //www.w3.org/Protocols/rfc2616/rfc2616-sec10.html