当前位置:  开发笔记 > 编程语言 > 正文

REST HTTP状态代码,用于验证失败或重复无效

如何解决《RESTHTTP状态代码,用于验证失败或重复无效》经验,为你挑选了8个好方法。

我正在使用基于REST的API构建一个应用程序,并且已经达到了为每个请求指定状态代码的程度.

对于未通过验证的请求或请求尝试在我的数据库中添加副本的情况,我应该发送什么状态代码?

我查看了http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,但似乎没有一个是正确的.

发送状态代码时是否有通用做法?



1> deamon..:

对于输入验证失败:400 Bad Request +您的可选说明.这在" RESTful Web Services " 一书中有所建议.对于双提交:409冲突


2014年6月更新

相关规范曾经是RFC2616,它使用了400(差错请求)

由于语法格式错误,服务器无法理解请求

因此可能有人认为它不适合语义错误.但不是更多; 自2014年6月起,相关标准RFC 7231(取代之前的RFC2616 )更广泛地使用400(错误请求)

由于被认为是客户端错误的东西,服务器不能或不会处理请求


错误的请求绝对是对此类问题最常见的回应.唯一的另一种选择是422 Unprocessable Entity.它实际上来自WebDav,但重用已在IANA注册的任何状态代码是完全有效的.
那么如何区分服务器甚至无法解析的格式错误的数据和验证错误?客户端将完全不同地处理这两个响应.为了验证,他们可能会向用户显示错误.对于真正"格式错误的数据",他们会记录错误,以便修复生成请求的方法中的错误.
我不同意你对RFC7231的解释,虽然它表示"被认为是客户端错误的东西",但本段中给出的所有示例都违反了HTTP协议,而不是逻辑错误:语法,成帧,路由.因此,我认为HTTP规范*不允许400在应用程序级别上进行失败验证.
409对于重复实体来说听起来相当不错,thnx
是的,请求正文是语法的一部分.

2> Piskvor cc-b..:

验证失败:403 Forbidden("服务器理解请求,但拒绝履行请求").与流行的观点相反,RFC2616没有说"403仅用于失败的身份验证",但"403:我知道你想要什么,但我不会这样做".该条件可能是也可能不是由于身份验证.

尝试添加副本:409 Conflict("由于与资源的当前状态冲突,无法完成请求.")

您应该在响应标头和/或正文中提供更详细的说明(例如,使用自定义标头 - X-Status-Reason: Validation failed).


"10.4.4 403禁止服务器理解了请求,但是拒绝完成它.授权不会帮助和请求不应该重复.如果请求方法不是头部和服务器希望为什么请求没有做出公开已经完成,它应该描述实体拒绝的原因.如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)代替." 我认为没有强调("应该/不应该"是RFC 2119关键字,而不是强调); 这是你的想法"禁止"意味着什么,而不是RFC的意思.
@deamon:那不是*规范,即维基百科,即某人对"HTTP状态代码的含义"的看法; 请注意,页面必须说"这就是Apache对403的意思,这就是IIS对403的意思",并且它没有引用官方RFC.你似乎在重复"403意味着Apache所说的".不.实际的RFC(这是相关文档,而不是Apache的实现,而不是IIS的实现,而不是其他任何人的实现)在这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
我喜欢这个答案,但仍然看到一个小问题.根据[规范](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html),当返回**403**时,"请求不应重复".但是,只有在预期用户可能能够解决冲突并重新提交请求的情况下,才允许返回**409**".在重复的情况下,我认为**403**更合适,因为您无法真正解决冲突(除非删除先前的资源实例).
IMO,422"无法处理的实体"更有意义.我的理由是,服务器_refuses_不是要完成请求,而是服务器_不能满足请求.
对于错误消息本身,您应该修改原因短语,因此发送标题"HTTP/1.0 403表单验证错误"是最简洁的方法.
来自RFC 7231:"403(禁止)状态代码表示服务器理解请求但拒绝__authorize__它."http://tools.ietf.org/html/rfc7231#section-6.5.3

3> Julian Resch..:

我建议使用状态码422,"Unprocessable Entity".

11.2.422不可处理的实体

422(不可处理实体)状态代码表示服务器理解请求实体的内容类型(因此415(不支持的媒体类型)状态代码是不合适的),并且请求实体的语法是正确的(因此400(错误请求) )状态代码不合适)但无法处理包含的指令.例如,如果XML请求主体包含格式正确(即语法正确)但语义错误的XML指令,则可能发生此错误情况.


deamon,这没有意义.HTTP定义了如何定义新代码,这就是WebDAV正在做的事情.有一个状态代码注册表是有原因的.
仅供参考 - 对422:11.2的RFC描述.422不可处理的实体422(不可处理的实体)状态代码表示服务器理解请求实体的内容类型(因此415(不支持的媒体类型)状态代码是不合适的),并且请求实体的语法是正确的(因此400 (错误请求)状态代码不合适)但无法处理包含的指令.例如,如果XML请求主体包含格式正确(即语法正确)但语义错误的XML指令,则可能发生此错误情况.
当然它是HTTP状态代码,请参阅http://www.iana.org/assignments/http-status-codes.状态代码多于RFC 2616中定义的状态代码.
WebDAV是HTTP**扩展**."用于Web分布式创作和版本控制的HTTP扩展(WebDAV)"因此,状态代码422不是http状态代码,而是http的extions的状态代码.
并且线程不会"过期".他们需要保持生活或顶级谷歌搜索结果开始变得不准确.
这就是Twitter现在使用的.不是说他们是法律,而是值得注意.
@TurtlePowered:我认为没有问题 - 评论中的一些讨论已经持续了多年,从字面上看.
我想要代码,现在我拥有它.我看不出有什么问题.

4> sethcall..:

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", ...]
    }
}

这种格式非常适合表单验证,我认为这是"错误报告丰富度"方面最复杂的案例.如果您的错误结构是这样,它可能会处理您的所有错误报告需求.


怎么样的args之间的相互作用产生的错误.也就是说,`arg1`是有效的,`arg2`是有效的,但是两者的组合,以及发送的特定值,是无效的.

5> 小智..:

数据库中的副本应该是a 409 CONFLICT.

我建议使用422 UNPROCESSABLE ENTITY验证错误.

我在这里给出了4xx代码的更长解释:http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/


409不是验证错误,Franta.

6> Marcodor..:

200

呃......(309,400,403,409,415,422)......很多答案试图猜测,争论并标准化成功的HTTP请求失败的REST调用的最佳返回码.

混合HTTP状态代码和REST状态代码是错误的.

但是,我看到很多实现混合它们,许多开发人员可能不同意我的观点.

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结果中的"错误"对象

如果未找到记录,则清空JSON数组/对象

bool结果/成功标志与之前的选项相结合,以便更好地处理.

此外,一些互联网服务提供商可能会拦截您的请求并返回404 HTTP代码.这并不意味着您的数据未找到,但在传输级别出现问题.

来自维基:

2004年7月,英国电信提供商BT集团部署了Cleanfeed内容阻止系统,该系统对因互联网观察基金会认定为可能违法的内容的任何请求返回404错误.其他ISP在相同的情况下返回HTTP 403"禁止"错误.泰国和突尼斯也报道了使用假404错误作为隐瞒审查手段的做法.在突尼斯,在2011年革命之前审查制度严重,人们开始意识到假404错误的性质,并创造了一个名为"Ammar 404"的虚构角色,代表"无形审查员".

为什么不简单回答这样的事情呢?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

即使请求在逻辑上失败,Google也会始终在其地理编码API中返回200作为状态代码:https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

即使REST请求失败,Facebook总是返回200以获得成功的HTTP请求:https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling

很简单,HTTP状态代码用于HTTP请求.REST API是您的,定义您的状态代码.


这个答案混淆了HTTP协议的原始语义与REST over HTTP如何作为_architectural style_ re-purpose HTTP来实现Web服务API.作为一种架构风格,REST不是严格遵循的标准,它是一种建议的方法.使用200响应进行验证失败是不对的,但是让客户回答请求成功,但实际上由于验证失败而失败,这是一个在响应体内隐藏的重要细节,客户端必须解析的语义才能理解.
@Marcodor如果您的API调用失败但返回200表示成功,这是一个好主意?对于API的消费者来说,这是不清楚和混乱的.
“因为谷歌做到了,这一定是对的”的说法对我来说是疯狂的。它可以挑战谷歌实现了孩子的东西。对于失败的rest调用返回HTTP 200会使API的调用者感到困惑,它应该是4xx,并且可以在主体中包含漂亮的JSON / XML ...让我们共同避免精神错乱。
正确的原因有很多,不仅仅是HTTP与REST错误的分离.REST验证通常需要更多细微差别.例如,记录已接受但标记为重复与拒绝唯一索引违规.您还需要一致的返回模型..NET`BadRequest()`方法有自己的返回模型,它与常规返回模型不同.这是解析的噩梦.@KevinHooke,返回HTTP 200以获得REST验证错误就像是说:"我收到了你的消息,答案是否定的,这就是原因." 返回HTTP 400说,"我不知道你在谈论什么."
实际上,使用REST的HTTP状态代码更加令人困惑:1)您在开发人员的工具箱中看到了4xx而您只能看一眼它是否服务器返回了一些合理的值或者根本没有处理您的请求然后2)所有你的错误/异常/捕获处理程序应检查哪些服务器作为响应返回(大多数情况下它们没有,因为你必须在每次服务调用时都这样做)多次3)你得到相同的负载(在成功和错误路径上导致复杂/重复的代码......确实很混乱.

7> Daniel Kmak..:

Ember-Data的ActiveRecord适配器期望422 UNPROCESSABLE ENTITY从服务器返回.因此,如果您的客户端是用Ember.js编写的,那么您应该使用422.只有这样DS.Errors才会填充返回的错误.您当然可以将422更改为适配器中的任何其他代码.



8> Suncat2000..:

状态代码304未修改也会对重复请求做出可接受的响应.这类似于处理If-None-Match使用实体标签的标头.

在我看来,@ Piskvor的答案是我认为原始问题的意图更明显的选择,但我有一个也是相关的替代方案.

如果要将重复请求视为警告或通知而不是错误,则响应状态代码" 304未修改"和Content-Location标识现有资源的标头将同样有效.当意图仅仅是为了确保资源存在时,重复请求不会是错误而是确认.请求没有错,但只是冗余,客户端可以引用现有资源.

换句话说,请求很好,但由于资源已经存在,服务器不需要执行任何进一步的处理.


据我所知,304用于GET操作以协助缓存.
推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有