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

我应该发送什么状态代码的请求失败验证或请求试图添加一个副本在我的数据库?

我已经在http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html上找过了,但是没有一个是对的。

发送状态码时有什么惯例吗?


当前回答

200

啊…(309、400、403、409、415、422)……大量的答案试图猜测,争论和标准化什么是一个成功的HTTP请求和一个失败的REST调用的最佳返回代码。

将HTTP状态代码和REST状态代码混合使用是错误的。

然而,我看到许多实现混合了它们,许多开发人员可能不同意我的观点。

HTTP返回码与HTTP请求本身相关。REST调用是使用超文本传输协议(Hypertext Transfer Protocol)请求完成的,它的工作级别比调用的REST方法本身要低。REST是一种概念/方法,其输出是业务/逻辑结果,而HTTP结果代码是传输结果。

例如,当你调用/users/时返回“404 Not found”是令人困惑的,因为它可能意味着:

URI错误(HTTP) 没有找到用户(REST)

“403禁止/拒绝访问”可能是指:

需要特别许可。浏览器可以通过询问用户/密码来处理它。(HTTP) 服务器上配置的访问权限错误。(HTTP) 您需要进行身份验证(REST)

这个列表可能会继续出现“500服务器错误”(Apache/Nginx HTTP抛出错误或REST中的业务约束错误)或其他HTTP错误等……

从代码中,很难理解失败的原因是什么,HTTP(传输)失败还是REST(逻辑)失败。

如果HTTP请求物理上被成功执行,它应该总是返回200个代码,不管是否找到记录。因为URI资源是由HTTP服务器找到并处理的。是的,它可能返回一个空集。有可能收到一个空网页200作为HTTP结果,对吗?

相反,你可以返回200个HTTP代码和一些选项:

如果出现错误,JSON结果中的"error"对象 如果没有发现记录,则为空JSON数组/对象 一个bool result/success标志,结合前面的选项以获得更好的处理。

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

从维基:

In July 2004, the UK telecom provider BT Group deployed the Cleanfeed content blocking system, which returns a 404 error to any request for content identified as potentially illegal by the Internet Watch Foundation. Other ISPs return a HTTP 403 "forbidden" error in the same circumstances. The practice of employing fake 404 errors as a means to conceal censorship has also been reported in Thailand and Tunisia. In Tunisia, where censorship was severe before the 2011 revolution, people became aware of the nature of the fake 404 errors and created an imaginary character named "Ammar 404" who represents "the invisible censor".

为什么不简单地这样回答呢?

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

谷歌总是在他们的地理编码API中返回200作为状态代码,即使在逻辑上请求失败:https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

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

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

其他回答

验证失败:403禁止(“服务器理解请求,但拒绝完成它”)。与流行的观点相反,RFC2616并没有说“403仅用于失败的身份验证”,而是说“403:我知道您想要什么,但我不会那样做”。这种情况可能是由于身份验证,也可能不是。 试图添加副本:409冲突(“由于与资源的当前状态冲突,请求无法完成。”)

你应该在响应头和/或正文中给出更详细的解释(例如,使用自定义头- X-Status-Reason: Validation failed)。

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

我推荐状态码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.

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

这种格式非常适合表单验证,我认为就“错误报告丰富度”而言,表单验证是最复杂的情况。如果您的错误结构是这样的,那么它可能会处理您所有的错误报告需求。

200

啊…(309、400、403、409、415、422)……大量的答案试图猜测,争论和标准化什么是一个成功的HTTP请求和一个失败的REST调用的最佳返回代码。

将HTTP状态代码和REST状态代码混合使用是错误的。

然而,我看到许多实现混合了它们,许多开发人员可能不同意我的观点。

HTTP返回码与HTTP请求本身相关。REST调用是使用超文本传输协议(Hypertext Transfer Protocol)请求完成的,它的工作级别比调用的REST方法本身要低。REST是一种概念/方法,其输出是业务/逻辑结果,而HTTP结果代码是传输结果。

例如,当你调用/users/时返回“404 Not found”是令人困惑的,因为它可能意味着:

URI错误(HTTP) 没有找到用户(REST)

“403禁止/拒绝访问”可能是指:

需要特别许可。浏览器可以通过询问用户/密码来处理它。(HTTP) 服务器上配置的访问权限错误。(HTTP) 您需要进行身份验证(REST)

这个列表可能会继续出现“500服务器错误”(Apache/Nginx HTTP抛出错误或REST中的业务约束错误)或其他HTTP错误等……

从代码中,很难理解失败的原因是什么,HTTP(传输)失败还是REST(逻辑)失败。

如果HTTP请求物理上被成功执行,它应该总是返回200个代码,不管是否找到记录。因为URI资源是由HTTP服务器找到并处理的。是的,它可能返回一个空集。有可能收到一个空网页200作为HTTP结果,对吗?

相反,你可以返回200个HTTP代码和一些选项:

如果出现错误,JSON结果中的"error"对象 如果没有发现记录,则为空JSON数组/对象 一个bool result/success标志,结合前面的选项以获得更好的处理。

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

从维基:

In July 2004, the UK telecom provider BT Group deployed the Cleanfeed content blocking system, which returns a 404 error to any request for content identified as potentially illegal by the Internet Watch Foundation. Other ISPs return a HTTP 403 "forbidden" error in the same circumstances. The practice of employing fake 404 errors as a means to conceal censorship has also been reported in Thailand and Tunisia. In Tunisia, where censorship was severe before the 2011 revolution, people became aware of the nature of the fake 404 errors and created an imaginary character named "Ammar 404" who represents "the invisible censor".

为什么不简单地这样回答呢?

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

谷歌总是在他们的地理编码API中返回200作为状态代码,即使在逻辑上请求失败:https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

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

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