HTTP状态422是否适用于未通过唯一性验证的记录?

时间:2013-03-05 13:44:01

标签: ruby-on-rails http-status-codes

我已经做了很多次(看到很多人这样做了),但我开始怀疑它是否合适:

if @record.save
  # status 200
else
  # failure of validations => status 422
end

现在我看到422 unprocessable entity表示request was well-formed, but not semantically correct。据我了解,验证错误可能不是语义错误。

注意:我说的是唯一性验证,因此我不确定这是否属于用户错误,如此问题:What's an appropriate HTTP status code to return by a REST API service for a validation failure?

总结一下:我应该停止使用状态422吗?如果是这样,我应该使用什么呢?

4 个答案:

答案 0 :(得分:34)

注意:试着在下面找一个详细的答案,但它似乎不可能,所以我会在这里回答。

我认为使用422进行验证错误很好。

  1. Webdav RFC并没有说422意味着语义错误"它表示服务器无法处理所包含的指令" (见http://tools.ietf.org/html/rfc4918#section-11.2)。 "语义错误"仅作为示例用例引用。

  2. 500保留用于"意外情况,导致其无法履行请求" (http://tools.ietf.org/html/rfc2616#section-10.5.1)。

  3. 500通常保留用于实际错误,例如代码中根本没有处理的事情,比如崩溃。处理验证错误,它们不是“意外的”,并且客户端必须更改请求以便可以处理(或不处理)。从这个意义上说,客户端犯了错误(例如,提交格式错误的电子邮件地址会引发验证错误,但显然它服务器错误,对吧?)。

    我见过的大多数API在这种情况下使用400或422。也许对此没有一个真正的答案,但是说500显然是我走的路。

    希望这有帮助。

答案 1 :(得分:17)

我同意 jbbarth ,它并不像422 vs 500那么简单。

422适用于验证错误,但您也不希望捕获db错误。

这是我使用的模式:

if @record.invalid?
  # failure of validations => status 422
elsif @record.save
  # status 200
else
  # failure when saving => status 500
end

答案 2 :(得分:9)

虽然返回422很好,但我说失败的唯一性验证应该返回409冲突。

答案 3 :(得分:3)

我的理解是,当HTTP请求正确但您在服务器端失败时 - 无论出于何种原因 - 那么您应该抛出5xx错误,表明存在服务器问题。除非您可以进一步指定,否则简单的500通常就足够了。

如果不是客户端的错,但是其他东西(客户端无法影响)阻止了记录被保存,那么它就是服务器错误,而不是HTTP通信意义上的(客户端)错误。