首页 文章

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

提问于
浏览
682

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

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

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

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

8 回答

  • 653

    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

    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

  • 6

    我推荐status code 422, "Unprocessable Entity" .

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

  • 6

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

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

  • 29

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


    Update June 2014

    过去的相关规范RFC2616,其中使用了400(差错请求)

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

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

    由于某些被认为是客户端错误的内容,服务器无法或不会处理请求

  • 12

    Ember-Data的ActiveRecord适配器需要从服务器返回 422 UNPROCESSABLE ENTITY . 因此,如果您的客户端是用Ember.js编写的,那么您应该使用422.只有这样DS.Errors才会填充返回的错误 . 适配器中的You can of course change 422 to any other code .

  • 256
    • 验证失败: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 ) .

  • 172

    数据库中的副本应为 409 CONFLICT .

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

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

  • 72

    Status Code 304 Not Modified也会对重复请求做出可接受的响应 . 这类似于使用实体标记处理 If-None-Match 的标头 .

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

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

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

相关问题