我正在使用基于REST的API构建一个应用程序,并且已经到了为每个请求指定状态代码的地步。
对于验证失败的请求,或者请求试图在数据库中添加副本的位置,我应该发送什么状态代码?
我浏览过http://www.w3.org/protocols/rfc2616/rfc2616-sec10.html,但没有一个是正确的。
发送状态代码时有没有常见的做法?
- 参见:stackoverflow.com/questions/1959947/…
- 打开httpstatus.es,右键单击>>Pin选项卡:p
- 对于验证失败,RESTAPI服务返回的适当HTTP状态代码可能是什么?
输入验证失败:400个错误请求+您的可选描述。这在"RESTful Web服务"一书中提出。双重提交:409冲突
2014年6月更新
相关规范过去是RFC2616,它给出了400(错误请求)的使用范围非常窄,因为
The request could not be understood by the server due to malformed syntax
所以可能有人认为它不适合于语义错误。但不再如此;自2014年6月起,取代先前的RFC2616的相关标准RFC7231将400(错误请求)的使用范围扩大到
the server cannot or
will not process the request due to something that is perceived to be
a client error
- 是的,请求主体是语法的一部分。
- 是的,400个错误的请求似乎是最接近的选择。
- 我将处理400个错误的请求和409个冲突,直到找到更适合我的东西。
- 错误的请求绝对是对此类问题最常见的响应。唯一的替代方案是422个不可加工实体。它实际上来自WebDAV,但是重用已经向IANA注册的任何状态代码是完全有效的。
- 那么,如何区分服务器甚至无法解析的格式错误数据和验证错误呢?客户机将以完全不同的方式处理这两个响应。为了进行验证,他们可能会向用户显示错误。对于真正的"格式错误的数据",他们会记录错误,以便修复生成请求的方法中的错误。
- 409听起来很适合复制实体,thnx
- 我不同意你对rfc7231的解释,虽然它指出something perceived to be a client error,但本段中给出的所有示例都违反了HTTP协议,而不是逻辑错误:语法、帧、路由。因此,我认为HTTP规范不允许400在应用程序级别验证失败。
- 为什么不使用422-不可加工实体?在我看来更符合逻辑
- 我同意409适用于重复,但有时重复是错误案例的副作用。例如,移动客户机在提交过程中可能会超时,并且永远不会接收到使用包含其所需ID的有效负载创建的201。我认为,在适当的时候(甚至可能的时候),另一种选择是303,重定向到超时之前创建的原始文件。
- 我已经阅读到HTTP/2中的自定义状态文本已被弃用,不幸的是找不到引用。
- 就我的2美分,我在某个地方读到,有时候Web服务器/浏览器会把4xx部分的代码调到00。
- 验证失败:403禁止("服务器理解请求,但拒绝完成请求")。与流行观点相反,RFC2616并没有说"403只用于认证失败",而是说"403:我知道你想要什么,但我不会这样做"。这种情况可能是由于身份验证造成的,也可能不是。
- 尝试添加重复的:409冲突("由于与资源的当前状态冲突,请求无法完成。")
您应该在响应头和/或主体中给出更详细的解释(例如,使用自定义头-X-Status-Reason: Validation failed)。
- "403禁止"有另一个语义。参见en.wikipedia.org/wiki/http_403
- @迪蒙:这不是规范,那是维基百科,也就是说,有人对"HTTP状态代码的含义"的看法;请注意,页面本质上说,"这是Apache对403的含义,这是IIS对403的含义",而没有提到正式的RFC。你似乎在重复"403意味着阿帕奇所说的一切"。不是。实际的RFC(这是相关文档,不是Apache的实现,不是IIS的实现,也不是其他任何实现)在这里:w3.org/protocols/rfc2616/rfc2616-sec10.html
- 我知道这个规格。重点是"禁止",意思是"在任何情况下拒绝访问"。
- "10.4.4 403禁止服务器理解请求,但拒绝执行。授权没有帮助,请求不应重复。如果请求方法不是head,并且服务器希望公开未满足请求的原因,那么它应该描述实体中拒绝的原因。如果服务器不希望向客户机提供这些信息,则可以使用状态代码404(未找到)来代替。"我在这里看不到重点("应该/不应该"是RFC 2119关键字,而不是重点);这就是"禁止"的意思,而不是RFC的意思。
- 我喜欢这个答案,但仍然看到一个小问题。根据规范,当返回403时,"请求不应重复"。但是,只有在预期用户可能能够解决冲突并重新提交请求的情况下,才允许返回409"。在复制的情况下,我认为403更合适,因为您不能真正解决冲突(除非删除资源的前一个实例)。
- 这是一个很好的答案。我同意piskvor的观点,无效的有效负载与请求的语法错误不一样。
- 对于错误消息本身,您应该修改原因短语,因此发送头部HTTP/1.0 403 Form validation errors是最干净的方式。
- 在阅读了RFC之后,这似乎是验证错误意义上最接近的匹配。
- 在我看来,422"不可加工实体"更有意义。我的理由是,不是服务器拒绝完成请求,而是服务器不能完成请求。
- 这可能是一个选择,是的。我试图严格遵守RFC2616——看看当@julian reschke在一个兄弟回答stackoverflow.com/a/3291292/19746中提到422时爆发的情绪。
- @piskvor,由于自定义HTTP头中的X-前缀已被弃用,您可以将示例更改为仅Status-Reason: Validation failed。
- @罗伯库尔斯:不赞成?[需要引文]
- @当然,piskvor:tools.ietf.org/html/rfc6648另请参见stackoverflow.com/a/3561399/45948
- @罗伯库尔斯:很有趣,谢谢。我会坚持使用Makes no recommendation as to whether existing"X-" parameters ought to remain in use or be migrated to a format without the"X-"; this is a matter for the creators or maintainers of those parameters.并保持原样。
- -1:403 Forbidden表示请求是可理解的;通常无效的输入表示不可理解的请求。
- 来自RFC7231:"403(禁止)状态代码表示服务器理解请求,但拒绝授权。"tools.ietf.org/html/rfc7231第6.5.3节
- @帕特里克西蒂:见出版日期和作者。我认为这个问题影响了你所链接的部分的措辞;)
- 被否决的答案,因为它不再有效,由于更新的2014年RFC7231,以前的400/409回答似乎最准确。
- 我投了赞成票,因为403更具象征性。如果我有一个403,并且没有描述性错误消息,至少我有一个线索。404重叠条件,然后我需要点挖掘。
我建议状态代码422,"不可处理实体"。
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
- 这不是HTTP状态代码
- WebDAV扩展!好的,没想到。
- 当然,它是一个HTTP状态代码,请参见iana.org/assignments/http-status-codes。状态代码比RFC2616中定义的多。
- @Deamon:说到非代码,您链接到的维基百科页面(在这个问题的某个地方)记录了一些由IIS服务器团队(403.4-需要SSL)发明的子状态(甚至不是语法上有效的HTTP状态代码-"状态代码元素是3位整数结果代码")。试着吃你的蛋糕也吃?
- WebDAV是HTTP扩展。"Web分布式创作和版本控制(WebDAV)的HTTP扩展"因此,状态代码422不是HTTP状态代码,而是HTTP扩展的状态代码。
- 执事,这没有道理。HTTP定义了如何定义新代码,这就是WebDAV所做的。有一个状态代码注册表是有原因的。
- 皮斯克沃,这真是个问题。这可能不会发生在当前草案中定义的注册程序下。
- Piskvor,哦,不在里面。很好。-)
- 这就是Twitter现在使用的。不是说他们是法律,但值得注意。
- 仅供参考-422的RFC说明:11.2。422不可处理实体422(不可处理实体)状态代码表示服务器了解请求实体的内容类型(因此415(不支持的媒体类型)状态代码不合适),请求实体的语法正确(因此400(错误请求)状态代码不合适),但无法处理包含的说明。例如,如果XML请求主体包含格式良好(即语法正确)但语义错误的XML指令,则可能发生此错误情况。
- 哦!我没有意识到我在添加一个近3年的评论。对不起的。
- @我认为这没什么问题-评论中的一些讨论已经持续了多年,字面上说。
- 线程不会"过期"。他们需要继续活下去,否则谷歌的顶级搜索结果开始变得不准确。
- 我想要代码,现在我有了。我看不出有什么问题。
200300、400、500都是非常普通的。如果你想要通用的,400就可以了。
422被越来越多的API使用,甚至被现成的Rails使用。
无论您为API选择哪个状态代码,都会有人不同意。但我更喜欢422,因为我认为‘400+文本状态’太普通了。另外,您没有利用JSON就绪的解析器;相反,带有JSON响应的422非常明确,并且可以传递大量错误信息。
说到JSON响应,我倾向于标准化本例的Rails错误响应,即:
1 2 3 4 5 6 7
| {
"errors" :
{
"arg1" : ["error msg 1","error msg 2", ...]
"arg2" : ["error msg 1","error msg 2", ...]
}
} |
这种格式非常适合表单验证,我认为这是"错误报告丰富性"方面最复杂的支持案例。如果您的错误结构是这样的,那么它可能会处理您所有的错误报告需求。
- 参数之间的交互会产生什么错误呢?也就是说,arg1是有效的,arg2是有效的,但这两个值和发送的特定值的组合是无效的。
- 我不会想得太多,只要挑一个似乎拥有这段关系的人。
- 或者两个参数都有错误。作为一个用户,我想我希望看到每个冲突字段上的错误。
- 好极了!.explicit优于implicit
数据库中的副本应该是409 CONFLICT。
对于验证错误,我建议使用422 UNPROCESSABLE ENTITY。
我在这里对4xx代码给出了更详细的解释:http://parker0phil.com/2014/10/16/rest_http_4xx_status_codes_syntax_and_semantics/
(P)200(p)(P)呃…(309,400,403,409,415,422)……A lot of answers trying to guess,argue and standard what is the best return code for a successful http://request but a failed rest call.(p)(P)It is wrong to MIX http://status codes and rest status codes.(p)(P)然而,我所看到的许多执行情况,他们,和许多发展者可能不同意我。(p)(P)http://return codes are related to the EDOCX1 English 0 Itself.a Rest call is done using a hypertest transfer protocol request and it works at a lower level than invoked rest method itself.Rest is a concept/approach,and its output is a business/logical result,while http://result code is a transport one.(p)(P)For example,returning"404 not found"when you call/users/is confused,because it may mean:(p)
- Uri is wrong(http)
- 不用户是发现(rest)
(P)"403 forbidden/access denied"may mean:(p)
- Special permission needed.Browsers can handle it by asking the user/password.(http)
- Wrong access permissions configured on the server.(http)
- You need to be authenticated(rest)
(P)and the list may continue with"500 server mistake"(An APACHE/NGINX http://thrown mistake or a business constraint mistake in rest)or other http://errors etc.(p)(P)从《守则》到理解什么是失败的原因,到(运输)失败或失败的原因,都是困难的。(p)(P)如果http://request physically was performed successful it should always return 200 code,regardless is the record(s)found or not.因为Uri Resource is found and was handled by the http://server.是的,它可以回到一个阁楼。It is possible to receive an empty web-page with 200 as http://result,right?(p)(P)Instead of this you may return 200 http://code with some options:(p)
- "错误"目标在JSon result if some goes wrong
- Empty JSon array/object if no record found
- a Bool result/success flag in combination with previous options for a better handling.
(P)Also,some Internet Providers may intervent your requests and return you a 404 http://code.This does not means that your data are not found,but it's some wrong at transport level.(p)(P)来自维基:(p)布尔奇1(P)为什么不干脆回答这个问题呢?(p)字母名称(P)Google Always Returns 200 as Status Code in their Geocoding API,even if the request logically fails:https://developers.google.com/maps/documentation/geograping/intro/(p)(P)Facebook always return 200 for successful http://requests,even if rest request fails:https://developers.facebook.com/docs/graph-api/using-graph-api/mistake-handling(p)(P)这很简单,http://status codes are for http://requests.Rest api is your,defining your status codes.(p)
- 实际上,将HTTP状态代码用于REST更让人困惑:1)您在开发人员的工具箱中看到4xx,您不能仅仅通过浏览它来判断服务器是否返回了一些合理的值或根本无法处理您的请求,然后2)所有的错误/异常/捕获处理程序都应该检查作为响应返回的服务器(大多数情况下,因为每次服务调用都必须这样做)而且很多时候3)在成功和错误路径上获得相同的有效负载(类型),从而导致复杂/重复的代码……确实很困惑。
- 这个答案混淆了HTTP协议的原始语义与作为体系结构样式的HTTP上的REST如何重新利用HTTP来实现Web服务API。作为一种建筑风格,休息不是严格遵循的标准,它是一种建议的方法。对验证失败使用200响应并不是对的或错的,但是对于您的客户机来说,响应请求成功是令人困惑的,但实际上由于验证失败而失败了,这是一个重要的细节,在响应的主体中是模糊的,客户机必须解析它才能理解其语义。
- @Kevinhooke,这个答案解释了为什么使用HTTP返回代码是REST状态调用的坏主意。
- @如果您的API调用失败,但返回200表示成功,这是一个好主意吗?这对于您的API的消费者来说是不清楚和混乱的。
- 纠正的原因有很多,不仅仅是HTTP和REST错误的分离。REST验证通常需要更多的细微差别。例如,记录被接受但标记为重复,而不是因唯一索引冲突而被拒绝。您还需要一个一致的返回模型。.NET BadRequest()方法有自己的返回模型,与常规返回模型不同。这是一场噩梦。@Kevinhooke,返回HTTP 200作为一个REST验证错误就像说,"我收到了你的消息,答案是否定的,这就是为什么。"返回HTTP 400说,"我不知道你在说什么。"
- "因为谷歌做到了,它一定是对的"这一论点对我来说是疯狂的……挑战谷歌已经实现的孩子们的东西是可以的。为一个不成功的REST调用返回HTTP200会混淆API的调用者,它应该是4xx,并且可以在主体中包含一个漂亮的JSON/XML…让我们一起停止这种疯狂吧。
- @Jerylcook,上一个阶段是在一年的原始答案之后,我加入了Google,在一次集成中意外地发现了Google的工作原理。我想:嘿,谷歌读了这个答案,他们认为我是对的,他们抄袭了我。我应该要版税。:)我认为我对来电混乱争论得够多了……HTTP状态代码用于HTTP请求。休息代码:定义你自己。HTTP代码对于复杂的API设计来说是不够的。我们用汤匙喝汤吧,不要用叉子。
- 哦,H.。T,只是看看Facebook是怎么做到的,疯了…他们也抄袭了我)developers.facebook.com/docs/graph api/using graph api/…
- 如果一些Google项目资源返回2xx,而另一些返回4x,您会怎么说?你都查过了吗?谷歌是个大公司,他们经常失败。他们也有很多好东西。所以当你提到某个公司时,这不是一个论点,而是一个例证。你提出的想法对我来说是新的,并且有一定的意义,但是作为一个标准,如何将它与HTTP进行比较呢?
Ember数据的ActiveRecord适配器期望从服务器返回422 UNPROCESSABLE ENTITY。所以,如果您是客户,那么您应该使用422。只有ds.errors才会被返回的错误填充。当然,您可以将422更改为适配器中的任何其他代码。
状态代码304未修改也会对重复请求作出可接受的响应。这类似于使用实体标记处理If-None-Match的头文件。
在我看来,@piskvor的回答是对我所感知的原始问题的意图的更明显的选择,但是我有一个同样相关的选择。
如果要将重复请求视为警告或通知而不是错误,则未修改304的响应状态代码和标识现有资源的Content-Location头将同样有效。当目的仅仅是确保资源存在时,重复请求将不是一个错误,而是一个确认。请求没有错,只是冗余的,客户机可以引用现有的资源。
换句话说,请求是好的,但是由于资源已经存在,服务器不需要执行任何进一步的处理。