我正在使用基于rest的API构建一个应用程序,并且已经到了为每个请求指定状态代码的地步。
我应该发送什么状态代码的请求失败验证或请求试图添加一个副本在我的数据库?
我已经在http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html上找过了,但是没有一个是对的。
发送状态码时有什么惯例吗?
我正在使用基于rest的API构建一个应用程序,并且已经到了为每个请求指定状态代码的地步。
我应该发送什么状态代码的请求失败验证或请求试图添加一个副本在我的数据库?
我已经在http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html上找过了,但是没有一个是对的。
发送状态码时有什么惯例吗?
当前回答
验证失败:403禁止(“服务器理解请求,但拒绝完成它”)。与流行的观点相反,RFC2616并没有说“403仅用于失败的身份验证”,而是说“403:我知道您想要什么,但我不会那样做”。这种情况可能是由于身份验证,也可能不是。 试图添加副本:409冲突(“由于与资源的当前状态冲突,请求无法完成。”)
你应该在响应头和/或正文中给出更详细的解释(例如,使用自定义头- X-Status-Reason: Validation failed)。
其他回答
对于输入验证失败:400坏请求+您的可选描述。这在“rest式Web服务”一书中得到了建议。 对于双重提交:409冲突
2014年6月更新
相关的规范曾经是RFC2616,它给出了400(坏请求)的使用范围相当狭窄
由于语法错误,服务器无法理解请求
因此,可能有人认为它不适用于语义错误。但现在不是了;自2014年6月起,相关标准RFC 7231取代了之前的RFC2616,更广泛地使用400(坏请求)
服务器不能或 将不会处理请求由于某些东西被认为是 客户端错误
验证失败:403禁止(“服务器理解请求,但拒绝完成它”)。与流行的观点相反,RFC2616并没有说“403仅用于失败的身份验证”,而是说“403:我知道您想要什么,但我不会那样做”。这种情况可能是由于身份验证,也可能不是。 试图添加副本:409冲突(“由于与资源的当前状态冲突,请求无法完成。”)
你应该在响应头和/或正文中给出更详细的解释(例如,使用自定义头- X-Status-Reason: Validation failed)。
数据库中的副本应该是409冲突。
我建议使用422 UNPROCESSABLE ENTITY来处理验证错误。
我在这里对4xx代码做了更详细的解释。
Ember-Data的ActiveRecord适配器期望从服务器返回422个UNPROCESSABLE ENTITY。所以,如果你的客户端是用Ember.js编写的,你应该使用422。只有这样DS。错误将用返回的错误填充。当然,您可以将422更改为适配器中的任何其他代码。
我得出的结论是尝试遵循这个规则:如果它表明客户端开发人员错误,那么使用400(坏请求)。否则,假设根本没有客户端验证,如果哑用户输入无效数据,则使用422(不可处理实体)。如果有疑问,最好使用422,或者使用更容易实现的版本。
这有助于开发人员了解到底是谁犯了错误,是他自己还是用户。
所谓笨用户,我指的是非技术用户。攻击者在这里不重要:如果您担心这个问题,您就不会首先使用HTTP状态码。:)
例如,如果您正在根据JSON模式验证JSON请求体,400是正确的选择(例如缺少键,关键字不匹配)。但是,如果您希望用户输入一个有效的电子邮件,那么您应该使用422(让我再说一遍,假设没有客户端验证)。
这对更好的分支逻辑也很有帮助。例如,在REST API的上下文中,假设您有一个调查响应端点,可能使用POST和PATCH方法。在这种情况下,如果客户端发送了一个无效的POST请求,您可能希望在Location报头中返回新资源的URI,用于状态码为422时,而不是用于400时。
真实世界的例子当然更复杂,但我认为这应该很管用。