私が取り組んでいる "RESTのような" APIを使用して、さまざまなシナリオで正しいステータスコードを返すようにしています。 JSONフォーマットでのPOST購入を可能にするエンドポイントがあるとしましょう。それはこのように見えます:
{
"account_number": 45645511,
"upc": "00490000486",
"price": 1.00,
"tax": 0.08
}
クライアントが(予想される「税」の代わりに)「sales_tax」を送ってきた場合に何を返すべきですか。現在、私は400を返しています。しかし、私はこれについて自分自身に質問し始めました。本当に422を返すべきですか?つまり、JSON(これはサポートされています)と有効なJSONです。必須フィールドのすべてが含まれているわけではありません。
400 Bad Requestが、ユースケースに最適なHTTP/1.1ステータスコードになりました。
質問の時点で(および私の元の回答)、 RFC 7231 は問題ではありませんでした。 RFC 2616 が言ったので、私は400 Bad Request
に反対しました(私のものを強調して):
サーバーはリクエストを理解できませんでした構文が正しくないため。
記述したリクエストは、構文的に有効なHTTPで囲まれた構文的に有効なJSONであるため、サーバーはリクエストの構文に問題はありません。
ただしコメントでLee Saferiteが指摘したように 、 RFC 7231はRFC 2616を廃止し、その制限は含まれません :
400(Bad Request)ステータスコードは、クライアントエラー(たとえば、不正なリクエスト構文、無効なリクエストメッセージフレーミング、または不正なリクエストルーティング)として認識される何かが原因で、サーバーがリクエストを処理できない、または処理しないことを示します。
ただし、その言い回しの前に(または、RFC 7231がproposed標準であると今すぐ言いたい場合)、422 Unprocessable Entity
はincorrect使用例のHTTPステータスコード。これは、 としてRFC 4918の概要が次のように述べているためです。
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からのものを使用すべきではないと反対する人もいます。
状況を明示的にカバーしない元の標準のエラーコードを使用するか、状況を正確に説明する拡張機能からのエラーコードを使用するかの選択を考えると、後者を選択します。
さらに、 RFC 4918 Section 21.4 は IANA Hypertext Transfer Protocol(HTTP)Status Code Registry を指し、422が見つかります。
HTTPクライアントまたはサーバーがそのレジストリからのステータスコードを正しく使用する限り、それを使用することは完全に合理的であることを提案します。
しかし、HTTP/1.1の時点では、 RFC 7231 に牽引力があるため、400 Bad Request
を使用してください!
2015年現在のステータスを反映するには:
動作的には400と422の両方のレスポンスコードはクライアントと仲介者によって同じように扱われるので、実際にはconcreteの違いはありません。
しかし、現在400がもっと広く使われていることを期待しています。さらに、 HTTPbis仕様 が提供する明確化によって、2つのステータスコードのうち、より適切なものになっています。
文脈としては、HTTPbisはHTTP/1.1仕様の改訂版で、不明確または矛盾するところを明確にしようとしています。承認されたステータスに達すると、RFC2616に優先します。
400不正な要求 はあなたのユースケースにふさわしいHTTPステータスコードです。コードはHTTP/0.9-1.1 RFCで定義されています。
不正な構文のため、要求をサーバーで理解できませんでした。クライアントは変更なしにリクエストを繰り返すべきではありません(SHOULD NOT)。
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を使用しても問題ありません 。
正しい構文はありません。リクエストに対する「構文」の定義が何であるかによって異なるためです。最も重要なことはあなたです:
ここに正しい答えも間違った答えもないと言ってみんなが私の中を飛び越える前に、私がどのように結論に至ったのかについて少し説明しましょう。
この特定の例では、OPの質問は、予想されたものとは異なるキーを含むJSONリクエストに関するものです。今、受け取ったキー名は、自然言語の観点からは予想されるキーと非常に似ていますが、厳密には異なり、したがって(通常は)同等であるとはマシンによって認識されていません。
私が上で言ったように、決定要因は 構文 によって意味されるものです。リクエストがapplication/json
のコンテンツタイプで送信された場合、はい、リクエストは有効なJSON構文なので 構文的に validですが、 意味的には無効です valid - 期待されるものと一致しないため。 (問題の要求を意味的に有効にするものか無効にするものの厳密な定義を想定しています)。
一方、application/vnd.mycorp.mydatatype+json
のように、予想されるフィールドを正確に指定する、より具体的なカスタムコンテンツタイプでリクエストが送信された場合、リクエストは構文的に無効である可能性があり、したがって400レスポンスになります。
問題の場合、 value ではなく key が間違っていたので、 構文 error 指定があった場合 /有効なキーが何かについて/ /がありました。 指定がなかった場合 有効なキーの場合、または エラーの値が の場合、 セマンティック errorになります。
ケーススタディ: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" } ] }
422処理不能エンティティの説明更新日:2017年3月6日
422 Unprocessable Entityとは何ですか?
リクエストが整形式の場合、422ステータスコードが発生しますが、意味エラーのために処理できません。このHTTPステータスはRFC 4918で導入され、より具体的にはWeb分散オーサリングとバージョン管理(WebDAV)のHTTP拡張機能を対象としています。
開発者が400と422のエラーをクライアントに返すべきかどうかについては、いくつかの論争があります(以下の両方のステータスの違いに関する詳細)。ただし、ほとんどの場合、422ステータスはWebDAV機能をサポートしている場合にのみ返されるべきであることに同意します。
RFC 4918のセクション11.2から取られた422ステータスコードのWord-to-Word定義は以下に読むことができます。
422(Unprocessable Entity)ステータスコードは、サーバーが要求エンティティのコンテンツタイプを理解しているため(415(Unsupported Media Type)ステータスコードは不適切です)、要求エンティティの構文は正しい(したがって400(Bad Request)です) )ステータスコードは不適切ですが、含まれている命令を処理できませんでした。
定義は次のように続きます:
例えば、このエラー状態は、XML要求本体が整形式(すなわち、構文的には正しい)だが意味的に誤りのあるXML命令を含む場合に発生する可能性がある。
400と422のステータスコード
不正な要求エラーは400ステータスコードを利用するため、要求の構文が不正である、無効な要求メッセージのフレーミングが含まれている、または不正な要求ルーティングがある場合はクライアントに返される必要があります。このステータスコードは422 unprocessable entityステータスとかなり似ているように見えますが、それらを区別する1つの小さな情報は、422エラーに対するリクエストエンティティの構文は正しいのに対して400を生成するリクエストの構文は正しいという事実です。エラーが正しくありません。
422ステータスの使用は非常に特定のユースケースのためにだけ予約されるべきです。不正な構文が原因でクライアントエラーが発生した他のほとんどの場合は、400 Bad Requestステータスを使用する必要があります。
まずこれはとても良い質問です。
例えば承認ヘッダーまたはコンテンツタイプヘッダー。これは、サーバーが要求を理解するために絶対に必要です。これはサーバーごとに異なります。
これは400より深刻ではありません。要求はサーバーに到達しました。サーバーは、要求が基本構造を正しく持っていることを確認しました。しかし、要求本体の情報を解析または理解することはできません。
例えばリクエストボディがJSONの場合はContent-Type: application/xml
。
ステータスコードとREST APIでのその使用方法を一覧にした記事があります。 https://metamug.com/article/status-codes-for-rest-api.php
あなたのケース: HTTP 400
は、RESTから見たあなたのケースの正しいステータスコードです。構文上正しくないので、tax
の代わりにsales_tax
を送信してください。ただし、有効なJSONです。これは通常、JSONをオブジェクトにマップするときにほとんどのサーバーサイドフレームワークによって実施されます。ただし、JSONオブジェクトの新しいkey
を無視するREST実装がいくつかあります。その場合、有効なフィールドのみを受け入れるカスタムのcontent-type
指定をサーバーサイドで実施できます。
422の理想的なシナリオ:
理想的な世界では、 422 が推奨され、サーバーが要求エンティティのコンテンツタイプを理解し、要求エンティティの構文は正しいが、データを処理できなかった場合は応答として送信することが一般的に受け入れられます。意味的に誤っています。
422を超える400の状況:
レスポンスコード422は拡張HTTP(WebDAV)ステータスコードです。 422を処理する準備ができていないHTTPクライアント/フロントエンドライブラリがまだいくつかあります。それらのために、それは"HTTP 422は間違っている、間違っている"のように単純です。サービスの観点からすると、400はあまり明確ではありません。
エンタープライズアーキテクチャでは、サービスは主にSOA、IDMなどのサービス層に配置されます。それらは通常、非常に古いネイティブクライアントから最新のHTTPクライアントまで、複数のクライアントにサービスを提供します。クライアントの1つがHTTP 422を処理しない場合、すべての人に対してレスポンスコードをHTTP 400にアップグレードまたは変更するようにクライアントに依頼することができます。私の経験では、これは最近非常にまれですがまだ可能性があります。そのため、HTTPレスポンスコードを決定する前に、アーキテクチャの慎重な検討が常に必要です。
このような状況に対処するために、サービス層は通常、厳密なHTTP準拠クライアントにはversioning
またはsetup 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は依然として本物の応答です。