28

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

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

现在我看到这422 unprocessable entity意味着请求格式正确,但语义不正确。据我了解,验证错误可能不是语义错误。

注意:我说的是唯一性验证,所以我不确定这是否属于用户错误,如以下问题所示:REST API 服务为验证失败返回什么适当的 HTTP 状态代码?

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

4

4 回答 4

36

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

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

  1. Webdav RFC 没有说 422 意味着“语义错误”,它说服务器“无法处理包含的指令”(参见https://www.rfc-editor.org/rfc/rfc4918#section-11.2)。“语义错误”仅作为示例用例引用。

  2. 500 保留用于“阻止它完成请求的意外情况”(https://www.rfc-editor.org/rfc/rfc2616#section-10.5.1)。

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

我见过的大多数 API 在这种情况下都使用 400 或 422。也许对此没有一个真正的答案,但说 500 是显而易见的方法对我来说似乎是错误的。

希望这可以帮助。

于 2013-08-17T01:38:29.283 回答
17

我同意jbbarth的观点,它不像422vs那样简单500

422对验证错误很有用,但您也不想捕获数据库错误。

这是我使用的模式:

if @record.invalid?
  # failure of validations => status 422
elsif @record.save
  # status 200
else
  # failure when saving => status 500
end
于 2014-02-06T02:13:17.527 回答
10

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

于 2015-02-26T02:10:21.617 回答
2

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

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

于 2013-03-06T17:21:18.450 回答