什么是适当的REST响应代码的有效请求,但空的数据?
例如,您为users/9
运行GET请求,但没有用户ID为9。 哪个是最好的响应码?
- 200好
- 202接受
- 204无内容
- 400错误的请求
- 404没有find
TL; DR:使用404
看这个博客 。 它解释得很好。
博客对204
的评论总结:
-
204 No Content
作为浏览器的响应代码并不是非常有用(尽pipe根据HTTP规范,浏览器确实需要将其理解为“不改变视图”的响应代码)。 - 然而,
204 No Content
是非常有用的Ajax Web服务,可能要表明成功,而不必返回的东西。 (尤其是在DELETE
或POST
不需要反馈的情况下)。
因此,对你的问题的答案是在你的情况下使用404
。 204
是一个专门的响应代码,您不应该经常返回到浏览器响应GET
。
其他响应代码甚至比204
和404
更合适。
-
200
应该返回与您成功提取的任何内容。 当您正在提取的实体不存在时不适用。 - 当服务器已经开始在一个对象上工作,但该对象还没有完全准备好时,使用
202
。 当然不是这里的情况。 您还没有开始,也不会开始构build用户9来响应GET
请求。 这打破了各种规则。 -
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