我正在使用基于REST的API构建应用程序,并且到了我为每个请求指定状态代码的地步。
对于未通过验证的请求,或者请求尝试在数据库中添加重复项的状态,我应该发送什么状态代码?
我已经浏览了http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,但是似乎都不对。
发送状态代码时是否有惯例?
我正在使用基于REST的API构建应用程序,并且到了我为每个请求指定状态代码的地步。
对于未通过验证的请求,或者请求尝试在数据库中添加重复项的状态,我应该发送什么状态代码?
我已经浏览了http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,但是似乎都不对。
发送状态代码时是否有惯例?
Answers:
对于输入验证失败:400错误的请求 +您的可选描述。在“ RESTful Web服务 ” 一书中建议这样做。对于双重提交:409冲突
2014年6月更新
相关规范以前是RFC2616,它给出了400(错误请求)的使用范围,
由于语法格式错误,服务器无法理解该请求
因此,可能有人认为它不适合语义错误。但是没有更多了。自2014年6月起,相关标准RFC 7231(取代了先前的RFC2616 )在以下方面更广泛地使用了400(错误请求):
由于某些原因,服务器无法或将不会处理请求,因为这被视为客户端错误
something perceived to be a client error
本段中给出的所有示例都违反了HTTP协议,而不是逻辑错误:语法,成帧,路由。因此,我认为HTTP规范并没有让400在应用层上验证失败。
您绝对应该在响应标头和/或正文中提供更详细的说明(例如,使用自定义标头- X-Status-Reason: Validation failed
)。
HTTP/1.0 403 Form validation errors
是最干净的方法。
我建议使用状态码422“无法处理的实体”。
11.2。422无法处理的实体
422(不可处理实体)状态代码表示服务器理解请求实体的内容类型(因此415(不支持的媒体类型)状态代码不合适),并且请求实体的语法正确(因此400(错误请求) )状态代码不合适),但无法处理其中的说明。例如,如果XML请求主体包含格式正确(即,语法正确)但语义上错误的XML指令,则可能发生此错误情况。
200,300、400、500都是非常通用的。如果要通用,则400即可。
422被越来越多的API使用,甚至被Rails开箱即用。
无论您为API选择哪种状态代码,都会有人不同意。但是我更喜欢422,因为我认为“ 400 +文本状态”过于笼统。另外,您没有利用JSON就绪的解析器;相反,带有JSON响应的422非常明确,并且可以传达大量错误信息。
说到JSON响应,我倾向于针对这种情况对Rails错误响应进行标准化,即:
{
"errors" :
{
"arg1" : ["error msg 1", "error msg 2", ...]
"arg2" : ["error msg 1", "error msg 2", ...]
}
}
这种格式非常适合表单验证,就“错误报告丰富性”而言,我认为这是最复杂的情况。如果您的错误结构是这样,它将可能满足您所有的错误报告需求。
arg1
有效且arg2
有效,但是两者的组合以及发送的特定值无效。
200
......(309,400,403,409,415,422)...很多答案试图猜测,争论和标准化什么是成功HTTP请求但失败REST调用的最佳返回码。
这是错误的混合使用HTTP状态代码和REST状态代码。
但是,我看到许多实现混在一起,许多开发人员可能不同意我的看法。
HTTP返回码与HTTP Request
自身相关。REST调用是使用超文本传输协议请求完成的,它的工作级别比调用的REST方法本身低。REST是一种概念/方法,其输出是业务/逻辑结果,而HTTP结果代码是一种传输结果。
例如,在调用/ users /时返回“ 404 Not found”很容易混淆,因为这可能意味着:
“ 403禁止/拒绝访问”可能表示:
并且该列表可能会继续显示“ 500服务器错误”(Apache / Nginx HTTP抛出错误或REST中的业务约束错误)或其他HTTP错误等。
从代码中,很难理解什么是失败原因,HTTP(传输)失败或REST(逻辑)失败。
如果HTTP请求在物理上成功执行,则无论是否找到记录,它都应始终返回200代码。因为找到 URI资源并由HTTP服务器处理。是的,它可能会返回一个空集。是否可以接收到一个以200为HTTP结果的空网页,对吗?
取而代之的是,您可能会返回200 HTTP代码和一些选项:
另外,某些互联网提供商可能会拦截您的请求并返回404 HTTP代码。这并不意味着未找到您的数据,但是在传输级别是有问题的。
从维基:
2004年7月,英国电信提供商BT Group部署了Cleanfeed内容阻止系统,该程序将对Internet Watch Foundation认定为潜在违法的任何内容请求返回404错误。在相同的情况下,其他ISP返回HTTP 403“禁止”错误。泰国和突尼斯也有报道采用伪造的404错误作为掩盖审查的手段。在突尼斯,2011年革命之前审查制度很严厉,人们开始意识到伪造的404错误的性质,并创建了一个假想的人物,名为“ Ammar 404”,代表“无形的审查者”。
为什么不简单地回答这样的事情呢?
{
"result": false,
"error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}
即使请求在逻辑上失败,Google也会始终在其Geocoding API中返回200作为状态代码:https : //developers.google.com/maps/documentation/geocoding/intro#StatusCodes
即使REST请求失败,Facebook也会始终为成功的HTTP请求返回200:https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling
很简单,HTTP状态代码用于HTTP请求。REST API是Your,请定义您的状态代码。
BadRequest()
方法具有自己的返回模型,该模型与常规返回模型不同。那是一场噩梦。@KevinHooke,返回HTTP 200以获得REST验证错误,就像在说:“我收到了您的消息,答案是否定的,这就是原因。” 返回HTTP 400时说:“我不知道您在说什么。”
状态代码304未修改也会对重复的请求做出可接受的响应。这类似于处理If-None-Match
使用实体标签的标头。
在我看来,@ Piskvor的答案是最明显的选择,我认为这是原始问题的意图,但我有另一种选择也很重要。
如果要将重复的请求视为警告或通知而不是错误,则响应状态代码为304
未修改,并且Content-Location
标头标识现有资源将同样有效。当只是为了确保资源存在时,重复的请求不是错误而是确认。该请求没有错,但只是多余的,客户端可以引用现有资源。
换句话说,请求是好的,但是由于资源已经存在,因此服务器不需要执行任何进一步的处理。
Ember-Data的ActiveRecord适配器期望422 UNPROCESSABLE ENTITY
从服务器返回。因此,如果您的客户端使用Ember.js编写,则应使用422。只有这样,DS.Errors才会填充返回的错误。您当然可以将422更改为适配器中的任何其他代码。