我正在使用基于REST的API构建一个应用程序,并且已经达到了为每个请求指定状态代码的程度 .
如果请求未通过验证或请求尝试在我的数据库中添加副本,我应该发送什么状态代码?
我看了http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,但似乎没有一个是正确的 .
发送状态代码时是否有通用做法?
我正在使用基于REST的API构建一个应用程序,并且已经达到了为每个请求指定状态代码的程度 .
如果请求未通过验证或请求尝试在我的数据库中添加副本,我应该发送什么状态代码?
我看了http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,但似乎没有一个是正确的 .
发送状态代码时是否有通用做法?
8 回答
200
呃......(309,400,403,409,415,422)......很多答案试图猜测,争论并标准化成功的http请求的最佳返回码,但是休息呼叫失败 .
混合HTTP协议代码和REST结果是 wrong .
但是,我看到很多实现混合它们,许多开发人员可能不同意我的观点 .
HTTP返回码与
HTTP Request
本身相关 . REST调用是使用超文本传输协议请求完成的,它的工作级别低于调用的REST方法本身 . REST是一种概念/方法,其输出是业务/逻辑结果,而HTTP结果代码是传输结果 .例如,当您调用/ users /时返回“404 Not found”是混淆的,因为它可能意味着:
URI错误(HTTP)
找不到用户(REST)
“403 Forbidden / Access Denied”可能表示:
需要特殊许可 . 浏览器可以通过询问用户/密码来处理它 . (HTTP)
服务器上配置了错误的访问权限 . (HTTP)
您需要进行身份验证(REST)
该列表可能会继续“500服务器错误”(Apache / Nginx HTTP抛出错误或REST中的业务约束错误)或其他HTTP错误等...
从代码中,很难理解什么是失败原因,HTTP(传输)故障或REST(逻辑)故障 .
如果物理上成功执行了HTTP请求,它应始终返回200个代码,无论是否找到记录 . 因为找到了URI资源并由http服务器处理 . 是的,它可能会返回一个空集 . 是否有可能收到一个空的网页,其中200为http结果,对吗?
您可以使用以下选项返回200个HTTP代码:
如果出现问题,JSON结果中的
"error"对象
如果未找到记录,则清空JSON数组/对象
bool结果/成功标志与之前的选项相结合,以便更好地处理 .
此外,一些互联网服务提供商可能会拦截您的请求并返回404 http代码 . 这并不意味着您的数据未找到,但在传输级别出现问题 .
来自Wiki:
为什么不简单回答这样的事情呢?
Google始终在其地理编码API中返回200作为状态代码,即使请求在逻辑上失败:https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes
我推荐status code 422, "Unprocessable Entity" .
200,300,400,500都非常通用 . 如果你想要通用,那就400了 .
422由越来越多的API使用,甚至开箱即用的Rails使用 .
无论您为API选择哪种状态代码,都会有人不同意 . 但我更喜欢422,因为我认为“400文本状态”过于笼统 . 此外,您没有利用JSON就绪解析器;相反,具有JSON响应的422非常明确,并且可以传达大量错误信息 .
说到JSON响应,我倾向于对这种情况的Rails错误响应进行标准化,即:
这种格式非常适合表单验证,我认为这是“错误报告丰富度”方面最复杂的案例 . 如果您的错误结构是这样,它可能会处理您的所有错误报告需求 .
对于输入验证失败:400 Bad Request您的可选说明 . 这在“RESTful Web Services”一书中有所建议 . 双提交:409 Conflict
Update June 2014
过去的相关规范RFC2616,其中使用了400(差错请求)
因此可能有人认为它不适合语义错误 . 但不是更多;自2014年6月起,相关标准RFC 7231(取代之前的RFC2616)更广泛地使用400 (Bad Request)
Ember-Data的ActiveRecord适配器需要从服务器返回
422 UNPROCESSABLE ENTITY
. 因此,如果您的客户端是用Ember.js编写的,那么您应该使用422.只有这样DS.Errors才会填充返回的错误 . 适配器中的You can of course change 422 to any other code .验证失败:403禁止("The server understood the request, but is refusing to fulfill it") . 与流行的观点相反,RFC2616并没有说"403 is only intended for failed authentication",而是"403: I know what you want, but I won't do that" . 该条件可能是也可能不是由于身份验证 .
试图添加副本:409冲突("The request could not be completed due to a conflict with the current state of the resource.")
您肯定应该在响应标头和/或正文中提供更详细的说明(例如,使用自定义标头 -
X-Status-Reason: Validation failed
) .数据库中的副本应为
409 CONFLICT
.我建议使用
422 UNPROCESSABLE ENTITY
进行验证错误 .我在这里给出了4xx代码的更长解释:http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/
Status Code 304 Not Modified也会对重复请求做出可接受的响应 . 这类似于使用实体标记处理
If-None-Match
的标头 .在我看来,@ Piskvor的答案是我认为原始问题的意图更明显的选择,但我有一个也是相关的替代方案 .
如果要将重复请求视为警告或通知而不是错误,则标识现有资源的
304
Not Modified和Content-Location
标头的响应状态代码将同样有效 . 当意图仅仅是为了确保资源存在时,重复请求不会是错误而是确认 . 请求没有错,但只是冗余,客户端可以引用现有资源 .换句话说,请求很好,但由于资源已经存在,服务器不需要执行任何进一步处理 .