データのPOSTに対する400対422の応答


355

私が取り組んでいる「RESTのような」APIを使用して、さまざまなシナリオで返される正しいステータスコードを把握しようとしています。JSON形式でPOSTで購入できるエンドポイントがあるとします。次のようになります。

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}

クライアントが(予想される「税金」の代わりに)「sales_tax」を送った場合、何を返却すればよいですか。現在、私は400を返します。しかし、私はこれについて自分自身に質問し始めました。本当に422を返す必要がありますか?つまり、JSON(これはサポートされています)であり、有効なJSONです。必要なフィールドのすべてが含まれているわけではありません。


回答:


419

400 Bad Requestは、ユースケースに最適なHTTP / 1.1ステータスコードになりました。

あなたの質問(および私の最初の回答)の時点では、RFC 7231重要ではありませんでした。その時点で400 Bad RequestRFC 2616が(私を強調して)言っているため、私は反対しました。

不正な構文のため、サーバーはリクエストを理解できませんでした。

また、記述したリクエストは、構文的に有効なHTTPに格納された構文的に有効なJSONであるため、サーバーはリクエストの構文に問題がありません。

ただし 、Lee Saferiteがコメント指摘したようにRFC 2616を廃止したRFC 7231にはその制限が含まれていません

400(Bad Request)ステータスコードは、クライアントエラーであると認識される何か(たとえば、不正な形式の要求構文、無効な要求メッセージのフレーミング、または不正な要求ルーティング)により、サーバーが要求を処理できないか、または処理しないことを示します。


ただし、その言い直しの前に(または、RFC 7231が現在提案されている標準にすぎないかどうか疑問に思っている場合)、RFC 4918の概要にあるようにユースケースのHTTPステータスコードが正しく422 Unprocessable Entityないように見えることはありません

HTTP / 1.1によって提供されるステータスコードは、WebDAVメソッドで発生するほとんどのエラー状態を説明するのに十分ですが、既存のカテゴリに適切に分類されないエラーがいくつかあります。この仕様は、WebDAVメソッド用に開発された追加のステータスコードを定義します(セクション11)

そしての説明は422言う:

422(Unprocessable Entity)ステータスコードは、サーバーがリクエストエンティティのコンテンツタイプを理解しているため(415(Unsupported Media Type)ステータスコードが不適切)、リクエストエンティティの構文が正しい(つまり、400(Bad Request )ステータスコードが不適切)ですが、含まれている指示を処理できませんでした。

(構文への参照に注意してください。7231は4918も一部廃止されていると思います)

これはあなたの状況とまったく同じように聞こえますが、疑いがある場合に備えて、次のように続けます。

たとえば、XMLリクエストの本文に整形式(つまり、構文的には正しい)が含まれているが、意味的には誤りのあるXML命令が含まれている場合に、このエラー条件が発生することがあります。

(「XML」を「JSON」に置き換えてください。あなたの状況に同意できると思います)

さて、RFC 4918は「Web分散オーサリングとバージョン管理(WebDAV)のHTTP拡張機能」に関するものであり、(おそらく)WebDAVに関連することは何もしていないので、そこからのものを使用してはならないことに反対する人もいます。

状況を明示的にカバーしていない元の標準のエラーコードを使用するか、状況を正確に説明する拡張機能からエラーコードを使用するかを選択できるので、後者を選択します。

さらに、RFC 4918セクション21.4IANAハイパーテキスト転送プロトコル(HTTP)ステータスコードレジストリを参照しており、422が見つかります。

私は、HTTPクライアントまたはサーバーがそのレジストリからのステータスコードを正しく使用する限り、それらを使用することは完全に合理的であることを提案します。


しかし、HTTP / 1.1の時点では、RFC 7231が牽引力を持っているため、そのまま使用して400 Bad Requestください。


5
あなたの答え(422)は私には意味があります。これは、検証エラーのためにリソースを処理できなかった場合にRails(respond_with)が使用するものでもあります。
タイラーリック

11
非WebDAV仕様での422の使用に注意してください:tools.ietf.org/html/rfc5789#section-2.2
Andrey Shchekin 14年

4
更新と同様に、RFC 7231には、セマンティクスを変更する応答コード400の異なる記述があります。
Lee Saferite、2015

5
申し訳ありません。RFCの変更を反映するためにこの回答を更新し、いくつかの明確さを失いました。リファクタリングしてみます。ほぼ確実である安全な 422を使用することではなく、今ではすべきである 400を使用する
クリスチャンガラス

2
スペックはもっと明確になると思います。に示されている例は、クライアントが何か間違っていることの明らかなケースです。OPの状況もそのカテゴリに分類されます。ただし、「お伺いしたことはわかりましたが、何らかのビジネスルールがあるためお断りする」というケースも明確ではありません。これはクライアントの責任ではありません。したがって、同じ仕様に従って、実際には403が適用される可能性があります。私は許可に関連するものと「それはできません」に対して別々のコードを用意したいと思います。
Thorarin

37

400 Bad Requestは、ユースケースに適したHTTPステータスコードです。コードはHTTP / 0.9-1.1 RFCで定義されています。

不正な構文のため、サーバーはリクエストを理解できませんでした。クライアントは変更せずにリクエストを繰り返すべきではありません。

http://tools.ietf.org/html/rfc2616#section-10.4.1

422 Unprocessable EntityはRFC 4918-WebDavで定義されています。400と比較してわずかな違いがあることに注意してください。以下の引用テキストを参照してください。

このエラー状態は、XMLリクエストの本文に整形式(つまり、構文的には正しい)が含まれているが、意味的に誤りのあるXML命令が含まれている場合に発生することがあります。

インターフェースを統一するには、XML応答の場合にのみ422を使用し、422だけでなく、Webdav拡張で定義されたすべてのステータスコードもサポートする必要があります。

http://tools.ietf.org/html/rfc4918#page-78

ステータスコードに関するMark Nottinghamの投稿も参照してください。

アプリケーションの各部分をHTTPステータスコードに「深く」マッピングしようとするのは誤りです。ほとんどの場合、目標とする粒度のレベルははるかに粗くなります。よくわからない場合は、一般的なステータスコード200 OK、400 Bad Request、500 Internal Service Errorを使用しても問題ありません

HTTPステータスコードについて考える方法


4
422コードはIANAレジストリiana.org/assignments/http-status-codes/http-status-codes.xhtmlの一部であるため、どのIMHOも意味がありません。いずれにしても、FacebookおよびTwitter REST APIは独自のコードを再発明し、RFC / IANA標準を使用しません。できます。
ジヴェンコア2014

15
第11節は、特にそれらが全体の仕様に追加されている米国およびだけではなくWebDavの仕様内:The following status codes are added to those defined in HTTP/1.1 [RFC2616].
スティーブ・タウバー

8
コードがWebDAV仕様の一部として記述されているからといって、それがWebDAV固有のものであるとは限りません。ステータスコードは一般的なものです。
modをうまく処理する

33

2015年のステータスを反映するには:

動作上、400と422の両方の応答コードはクライアントと仲介者によって同じように扱われるため、実際に使用する具体的な違いはありません。

ただし、現在400がより広く使用されていることを期待します。さらに、HTTPbis仕様が提供する明確化により、2つのステータスコードのうち、より適切になります。

  • HTTPbis仕様は、400の意図が構文エラーのみに限定されないことを明確にしています。より広いフレーズ「クライアントエラーと認識されたものが原因で、サーバーが要求を処理できない、または処理しないことを示す」が使用されるようになりました。
  • 422は特にWebDAV拡張であり、RFC 2616または新しいHTTPbis仕様では参照されていません。

コンテキストについては、HTTPbisはHTTP / 1.1仕様の改訂版であり、不明確または一貫性のない領域を明確化しようとします。承認済みのステータスに達すると、RFC2616に優先します。


4
その場合、403 Forbiddenもこのコンテキストに使用されるのではないでしょうか?引用:403(禁止)ステータスコードは、サーバーが要求を理解したが、承認を拒否したことを示しています...認証資格情報が要求で提供された場合、サーバーはそれらをアクセスを許可するには不十分であると見なします....ただし、要求は資格に関係のない理由で禁止されている。 したがって、403は認証以外の要求を拒否するために使用できるように見えます。
garbagecollector 2015

1
@garbagecollectorは、「資格情報以外の理由で拒否されました」!=「認証以外の理由で拒否されました。」特に、資格情報を使用せずに誰かを認証する方法はたくさんあります。
Knetic

@garbagecollectorいいえ、資格情報は認証(「あなたは誰ですか」)を意味し、失敗すると401になります。承認(「何ができるか」)は、失敗すると403になります。ここでの完全な説明:stackoverflow.com/a/6937030/137948 OPの「フィールドがない」状況にはどちらも当てはまりません。なぜなら、どのユーザーがそれを試みたかに関係なく、エラーは同じだからです。400が正しい答えだと私は同意します。
シェパードは2017

27

ケーススタディ:GitHub API

https://developer.github.com/v3/#client-errors

よく知られているAPIからコピーするのが賢明なアイデアかもしれません。

リクエストの本文を受信するAPI呼び出しのクライアントエラーには、次の3つのタイプがあります。

無効なJSONを送信すると、400 Bad Request応答が返されます。

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}

間違ったタイプのJSON値を送信すると、400 Bad Request応答が返されます。

HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}

無効なフィールドを送信すると、422 Unprocessable Entityレスポンスが返されます。

HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}

これは正解で理解できる答えだと思います。
LEMUEL ADANE

1
それ以上賛成することはできません。より多くの賛成投票がこれに言及することを望みます。仕様(RFC、IANA)は明確な定義と2つの違いを明確に提供できませんでした。答えは結局ベストプラクティスに要約され、GitHubがそれを与えてくれます。
アレックスクラウス

15

正しい答えはありません。それは、「構文」の定義があなたのリクエストにとって何であるかに依存するためです。最も重要なことは、次のことです。

  1. 応答コードを一貫して使用する
  2. 何が起こっているのかをAPIを使用して開発者が理解できるように、できる限り多くの追加情報を応答本文に含めてください。=

誰もがここで正解か不正解がないと言って私を飛び越えて行く前に、私が結論に至った方法について少し説明しましょう。

この特定の例では、OPの質問は、予想とは異なるキーを含むJSONリクエストに関するものです。現在、受け取ったキーの名前は、自然言語の観点から、期待されるキーと非常に似ていますが、厳密に異なるため、(通常は)同等のマシンとして認識されません。

上で述べたように、決定的な要素は構文の意味です。リクエストがコンテンツタイプで送信された場合、application/jsonはい、リクエストは構文的には有効ですが、JSON構文は有効であるため、予想と一致しないため、意味的には有効ではありません。(問題のリクエストを意味的に有効にするものの厳密な定義を仮定すると)。

一方、リクエストがapplication/vnd.mycorp.mydatatype+jsonそのようなより具体的なカスタムコンテンツタイプで送信された場合、おそらく期待されるフィールドを正確に指定している場合、リクエストは構文的に無効である可能性が高いため、400レスポンスとなるでしょう。

問題のケースでは、ではなくキーが間違っていたため、有効なキーの指定があると構文エラーが発生しました。有効なキーの指定がない場合、またはエラーがvalue発生した場合は、セマンティックエラーになります。


非常に過小評価されている回答-よく説明された説明に感謝
puiu 2016年

まさに問題についての私の考え!私はXML SOAPのバックグラウンドから来ており、スキーマの概念は私の血に溶け込み、JSONドキュメントはスキーマを発表しません。私にとっては、サーバーが要求を「理解」するかどうかです。サーバーが「sales_tax」が何であるかを知らない場合、それは単に400です。
Aleksander Stelmaczonek 2017

4

422処理できないエンティティの説明の更新:2017年3月6日

422処理できないエンティティとは何ですか?

422ステータスコードは、リクエストが整形式である場合に発生しますが、セマンティックエラーのために処理できません。このHTTPステータスはRFC 4918で導入され、より具体的にはWeb分散オーサリングおよびバージョン管理(WebDAV)のHTTP拡張を対象としています。

開発者が400と422のエラーをクライアントに返すかどうかについては、いくつかの論争があります(以下の両方のステータスの違いについての詳細)。ただし、ほとんどの場合、422ステータスはWebDAV機能をサポートしている場合にのみ返されることに同意しています。

RFC 4918のセクション11.2から取得した422ステータスコードの単語ごとの定義を以下に示します。

422(Unprocessable Entity)ステータスコードは、サーバーがリクエストエンティティのコンテンツタイプを理解しているため(415(Unsupported Media Type)ステータスコードが不適切)、リクエストエンティティの構文が正しい(つまり、400(Bad Request )ステータスコードが不適切)ですが、含まれている指示を処理できませんでした。

定義は続けて言う:

たとえば、XMLリクエストの本文に整形式(つまり、構文的には正しい)が含まれているが、意味的には誤りのあるXML命令が含まれている場合に、このエラー条件が発生することがあります。

400と422のステータスコード

不正なリクエストエラーは400ステータスコードを利用するため、リクエストの構文が正しくない場合、無効なリクエストメッセージフレーミングが含まれている場合、または不正なリクエストルーティングがある場合は、クライアントに返す必要があります。このステータスコードは、422の処理不可能なエンティティのステータスと非常に似ているように見えるかもしれませんが、それらを区別する1つの小さな情報は、422エラーのリクエストエンティティの構文は正しいが、400を生成するリクエストの構文は正しいという事実です。エラーが不正です。

422ステータスの使用は、非常に特定のユースケースでのみ予約する必要があります。不正な構文のためにクライアントエラーが発生した他のほとんどの場合、400 Bad Requestステータスを使用する必要があります。

https://www.keycdn.com/support/422-unprocessable-entity/


1

あなたのケース: 有効なJSONですが、HTTP 400RESTの観点からはケースの正しいステータスコードです。これは通常、JSONをオブジェクトにマッピングするときに、ほとんどのサーバー側フレームワークによって適用されます。ただし、JSONオブジェクトのnewを無視するREST実装がいくつかあります。その場合、有効なフィールドのみを受け入れるカスタム仕様をサーバー側で適用できます。sales_taxtaxkeycontent-type

422の理想的なシナリオ:

理想的な世界では、サーバーがリクエストエンティティのコンテンツタイプを理解し、リクエストエンティティの構文は正しいが、意味的に誤りがあるためにデータを処理できなかった場合、422が優先され、一般的に応答として送信できます。

422を超える400の状況:

レスポンスコード422は拡張HTTP(WebDAV)ステータスコードであることを忘れないでください。422を処理する準備ができていないHTTPクライアント/フロントエンドライブラリがまだいくつかあります。それらにとって、「HTTPではないため、HTTP 422は間違っている」のように単純です。サービスの観点からは、400はそれほど具体的ではありません。

エンタープライズアーキテクチャでは、サービスは主にSOA、IDMなどのサービスレイヤーに展開されます。通常、サービスは非常に古いネイティブクライアントから最新のHTTPクライアントまでの複数のクライアントにサービスを提供します。クライアントの1つがHTTP 422を処理しない場合、オプションは、すべてのユーザーに対して応答コードをHTTP 400にアップグレードまたは変更するようにクライアントに要求することです。私の経験では、これは最近非常にまれですが、まだ可能性があります。そのため、HTTP応答コードを決定する前に、アーキテクチャを慎重に検討する必要があります。

このような状況を処理するために、サービス層は通常、厳密なHTTP準拠クライアントのフラグを使用versioningまたは設定configurationして、400を送信し、残りのクライアントには422を送信します。これにより、既存のコンシューマーに下位互換性のサポートを提供すると同時に、新しいクライアントがHTTP 422を使用できるようになります。


RFC7321の最新の更新は言う:

The 400 (Bad Request) status code indicates that the server cannot or
   will not process the request due to something that is perceived to be
   a client error (e.g., malformed request syntax, invalid request
   message framing, or deceptive request routing).

これにより、サーバーが無効なリクエストに対してHTTP 400を送信できることが確認されます。400はもはや構文エラーだけを参照しているわけではありませんが、422は、クライアントがそれを処理できる場合、本物の応答です。


1

まず、これは非常に良い質問です。

400 Bad Request-リクエストから重要な情報が欠落している場合

たとえば、認証ヘッダーまたはコンテンツタイプヘッダー。これは、サーバーが要求を理解するために絶対に必要です。これはサーバーごとに異なります。

422 Unprocessable Entity-リクエストの本文を解析できない場合。

これは400よりも重大ではありません。要求がサーバーに到達しました。サーバーは、リクエストが基本構造を正しく持っていることを認めました。ただし、リクエスト本文の情報は解析または理解できません。

たとえばContent-Type: application/xml、リクエストの本文がJSONの場合。

以下は、ステータスコードとREST APIでのその使用法をリストした記事です。 https://metamug.com/article/status-codes-for-rest-api.php


5
422は、構文は有効ですが、内容が無効であることを意味します。XMLが期待されている場所にJSONを送信するということは、構文が間違っていることを意味するため、この場合は400が正しい応答です。
Dirk

1
まさにダークが言ったように、422は構文的には有効なリクエストを意味します(解析および理解できます)が意味的には無効です
Jacek Obarymski 18/12/12

400:構文が無効なためにリクエストを処理できない場合(解析エラーなど)。422:データが無効なためにリクエストを処理できない場合(検証エラーなど)。
北の鳥

アプリケーション/ xmlのメディアタイプでJSONを送信することで、体が自動的に文法的に間違っていると、応答は400でなければなりませんので、422のためのあなたの例では有効ではありません
manemarron

-15

実際には「200 OK」を返す必要があり、応答の本文には、投稿されたデータで何が起こったかについてのメッセージが含まれます。次に、メッセージを理解するのはアプリケーションの責任です。

実は、HTTPステータスコードはまさにHTTPステータスコードです。そして、それらはアプリケーション層ではなく、トランスポート層でのみ意味を持つことを意図しています。アプリケーション層は、HTTPが使用されていることを実際に認識してはなりません。トランスポートレイヤーをHTTPからHoming Pigeonsに切り替えた場合、アプリケーションレイヤーには何の影響もありません。

非仮想の例を挙げましょう。あなたが女の子に恋をして、彼女があなたを愛しているが、彼女の家族がまったく別の国に引っ越したとします。彼女はあなたに彼女の新しいカタツムリのメールアドレスを与えます。当然、あなたは彼女にラブレターを送ることにしました。手紙を書いて封筒に入れ、封筒に彼女の住所を書いて、切手を貼って送ります。では、これらのシナリオを考えてみましょう

  1. あなたは通りの名前を書くのを忘れました。開封されていないレターが届き、アドレスが不正であるというメッセージが書かれています。リクエストが失敗し、受け取り側の郵便局はそれを処理できません。これは、「400 Bad Request」を受信するのと同じです。
  2. したがって、アドレスを修正し、手紙を再度送信します。しかし、運が悪かったため、通りの名前のスペルを間違えました。アドレスが存在しないことを伝えるメッセージが表示された手紙が再び届きます。これは、「404 Not Found」を受け取るのと同じです。
  3. アドレスを再度修正し、今回は正しくアドレスを書き込むことができます。あなたの女の子は手紙を受け取り、あなたに返信します。これは「200 OK」を受信するのと同じです。ただし、これは彼女が彼女の手紙に書いたものを好きになるという意味ではありません。それは単に、彼女があなたのメッセージを受け取り、あなたに返事を出したことを意味します。あなたが封筒を開けて彼女の手紙を読むまでは、彼女があなたを恋しく思っているのか、それともあなたと別れたいのかわからない。

つまり、「200 OK」が返されても、サーバーアプリに良いニュースがあるということではありません。それはそれがいくつかのニュースを持っていることを意味するだけです。

PS:422ステータスコードは、WebDAVのコンテキストでのみ意味があります。WebDAVを使用していない場合、422は他の非標準コードとまったく同じ標準的な意味を持ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.