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

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

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

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


当前回答

数据库中的副本应该是409冲突。

我建议使用422 UNPROCESSABLE ENTITY来处理验证错误。

我在这里对4xx代码做了更详细的解释。

其他回答

数据库中的副本应该是409冲突。

我建议使用422 UNPROCESSABLE ENTITY来处理验证错误。

我在这里对4xx代码做了更详细的解释。

我推荐状态码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", ...]
    }
}

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

我得出的结论是尝试遵循这个规则:如果它表明客户端开发人员错误,那么使用400(坏请求)。否则,假设根本没有客户端验证,如果哑用户输入无效数据,则使用422(不可处理实体)。如果有疑问,最好使用422,或者使用更容易实现的版本。

这有助于开发人员了解到底是谁犯了错误,是他自己还是用户。

所谓笨用户,我指的是非技术用户。攻击者在这里不重要:如果您担心这个问题,您就不会首先使用HTTP状态码。:)

例如,如果您正在根据JSON模式验证JSON请求体,400是正确的选择(例如缺少键,关键字不匹配)。但是,如果您希望用户输入一个有效的电子邮件,那么您应该使用422(让我再说一遍,假设没有客户端验证)。

这对更好的分支逻辑也很有帮助。例如,在REST API的上下文中,假设您有一个调查响应端点,可能使用POST和PATCH方法。在这种情况下,如果客户端发送了一个无效的POST请求,您可能希望在Location报头中返回新资源的URI,用于状态码为422时,而不是用于400时。

真实世界的例子当然更复杂,但我认为这应该很管用。

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

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