web-dev-qa-db-ja.com

HTTPステータス422は、一意性の検証に失敗したレコードに適していますか?

私は何度もそれをしました(そして多くの人がそうしているのを見てきました)が、それが適切かどうか疑問に思い始めます:

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

422 unprocessable entityは、 リクエストが整形式であったが、意味的には正しくなかったことを意味します 。私が理解しているように、検証エラーはセマンティックエラーではないかもしれません。

注:私は一意性検証について話しているので、この質問のように、これがユーザーエラーと見なされるかどうかはわかりません: 検証エラーに対してREST APIサービスによって返される適切なHTTPステータスコードは何ですか?

要約すると、ステータス422の使用を中止する必要がありますか?もしそうなら、代わりに何を使うべきですか?

26
m_x

注意:pokeの答えの下で詳細な答えを出そうとしましたが、それは可能ではないようなので、ここで答えます。

検証エラーに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 )。

500は通常、実際のエラー用に予約されています。クラッシュなど、コードでまったく処理されないもの。検証エラーが処理され、「予期しない」エラーではなく、クライアントは要求を変更して処理できるようにする(または処理できない)必要があります。その意味で、クライアントはエラーを発生させました(たとえば、不正な電子メールアドレスを送信すると、検証エラーがスローされますが、明らかにnotサーバーエラーですよね? )。

私が見たほとんどのAPIは、そのような場合に400または422を使用します。これに対する真の答えは1つではないかもしれませんが、500が明確な方法であると言うのは私には間違っているように見えました。

お役に立てれば。

34
jbbarth

jbbarthは、422500ほど単純ではないことに同意します。

422は検証エラーに適していますが、dbエラーもキャッチしたくありません。

これは私が使用するパターンです:

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

422を返すのは問題ありませんが、一意性の検証に失敗すると409の競合が返されるはずです。

9
Ho-Sheng Hsiao

私の理解では、HTTPリクエストは正しくてもサーバー側で何らかの理由で失敗した場合、5xxエラーをスローし、サーバーに問題があったことを示します。さらに指定できない限り、通常は単純な500で十分です。

それがクライアントのせいではなく、他の何か(クライアントが影響できない)によってレコードが保存されなかった場合、それはサーバーエラーであり、HTTP通信の意味での(クライアント)エラーではありません。

3
poke