論理エラーのためのHTTP 400(悪いリクエスト)、奇形ではない要求構文
-
23-10-2019 - |
質問
HTTP/1.1仕様(RFC 2616) の意味について次のことを言っています ステータスコード400、悪いリクエスト(§10.4.1):
要求は、奇形の構文のためにサーバーによって理解できませんでした。クライアントは、変更なしでリクエストを繰り返さないでください。
最近のいくつかのHTTPベースのAPIの間で一般的な慣行があるように思われます。 論理 ではなく 構文 リクエスト付きエラー。私の推測では、APIがこれを行っていると推測しています 400 (クライアントによる)および 500 (サーバー誘導)。非同性エラーを示すために400を使用することは受け入れられますか、それとも間違っていますか?受け入れられる場合、RFC 2616に注釈付きの参照があり、400の意図された使用に関するより多くの洞察を提供しますか?
例:
他のヒント
ステータス422(RFC 4918、セクション11.2) 頭に浮かぶ:
422(処理不可能なエンティティ)ステータスコードは、サーバーがリクエストエンティティのコンテンツタイプを理解することを意味します(したがって415(サポートされていないメディアタイプ)ステータスコードは不適切です)。 )ステータスコードは不適切です)が、含まれている命令を処理できませんでした。たとえば、XML要求本体によく形成された(つまり、構文的に正しい)が、意味的に誤ったXML命令が含まれている場合、このエラー条件が発生する場合があります。
HTTPBISは、400の悪い要求のフレージングに対処し、論理エラーもカバーするようにします。したがって、400には422が組み込まれます。
から https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
「クライアントのエラー(例えば、奇形の構文)のため、サーバーは要求を処理できないか、処理しません」
私はまた、論理エラーを表すために400を使用していましたが、この場合、SPECの読み方のために400を返すことは間違っていると言わざるを得ません。論理的なエラーは、他のエンティティとの関係が失敗しているか、満足していないため、他のエンティティに変更を加えることで、まさにその後に渡される可能性があるという論理的なエラーがあると思う理由があります。その従業員が存在しないときに、従業員を部門のメンバーとして(完全に仮説的に)追加しようとするように(論理エラー)。従業員が存在しないため、メンバーのリクエストとして従業員を追加すると失敗する可能性があります。しかし、従業員がシステムに追加された後、まったくまったく正確な要求が渡される可能性があります。
ちょうど私の2セント...私たちは最近RFCの言語を解釈するために弁護士と裁判官が必要です:)
ありがとう、ヴィッシュ
あなたの要求に誤ったデータを持っていると主張することができます は HTTPレベル(要求行、ヘッダーなど)での実際の要求が構文的に有効であっても、構文エラー。
たとえば、RESTFUL WEBサービスがカスタムXMLコンテンツタイプの投稿を受け入れることとして文書化されている場合 application/vnd.example.com.widget+xml
, 、そして代わりに、いくつかの意味のあるプレーンテキストまたはバイナリファイルを送信します。それを構文エラーとして扱うことは復活しているようです - リクエスト本体は予想される形式ではありません。
しかし、これをバックアップするための公式の言及はわかりませんが、いつものように、RFC 2616の解釈にかかっているようです。
アップデート: 改訂された文言に注意してください RFC7231§6.5.1:
400(悪い要求)ステータスコードは、クライアントエラー、例えば不正な要求の構文、無効な要求メッセージフレーミング、または欺ceptive要求ルーティングであると認識されているもののために、サーバーが要求を処理できないか、または処理しないことを示します。
現在廃止されたものよりもこの議論を支持しているようです RFC2616§10.4.1 それはただ言った:
要求は、奇形の構文のためにサーバーによって理解できませんでした。クライアントは、変更なしでリクエストを繰り返さないでください。
Java EEサーバーでは、URLが存在しない「Webアプリケーション」を参照する場合、400が返されます。それは「構文エラー」ですか?構文エラーの意味に依存します。はいと言うでしょう。
英語では、構文規則では、音声の一部間の特定の関係を規定しています。たとえば、「Bob Marries Mary」は、パターン{名詞 + Verb + Noun}に従うため、構文的に正しいです。 「ボブ結婚メアリー」は構文的に間違っているのに対し、{名詞 +名詞 +名詞}。
単純なurlisの構文{protocol +: + // + server +: + port}。これによれば "http://www.google.com:80「構文的に正しいです。
しかし、「abc://www.google.com:80」はどうですか?まったく同じパターンに従っているようです。しかし、実際には構文エラーです。なんで? 「ABC」は定義されたプロトコルではないためです。
重要なのは、400の状況があるかどうかを判断するには、キャラクターやスペース、区切り文字を解析する以上のものが必要だということです。また、有効な「音声の一部」とは何かを認識する必要があります。
これは難しいです。
私たちはすべきだと思います。
クライアントがリクエスト、ヘッダー、またはボディに変更を加える力がある場合にのみ、4XXエラーを返し、リクエストが同じ意図で成功するようになります。
予想される突然変異が発生していない場合、削除が発生しなかった場合、またはプットが何も変わらなかった場合、エラー範囲コードを返します。ただし、SPECは、新しい場所でリソースを作成するか、ペイロードを処理するために使用する必要があるとスペックが言っているため、投稿はより興味深いものです。
Vishの回答の例を使用して、リクエストが従業員のPriyaを部門マーケティングに追加するが、Priyaが見つからなかった場合、またはアカウントがアーカイブされる場合、これはアプリケーションエラーです。
リクエストは正常に機能し、アプリケーションルールに到達し、クライアントはすべてを適切に行い、ETAGが一致しました。
HTTPを使用しているため、リソースの状態に対するリクエストの効果に基づいて応答する必要があります。そして、それはあなたのAPIデザインに依存します。
おそらくあなたはこれを設計しました。
PUT { updated members list } /marketing/members
成功コードを返すと、リソースの「交換」が機能したことが示されます。リソースを入手すると、変更が反映されますが、そうではありません。
そのため、適切なネガティブHTTPコードを選択する必要があります。コードはアプリケーションではなくHTTPプロトコル用に強く意図されているため、それは難しい部分です。
公式のHTTPコードを読むと、これら2つは適切に見えます。
409(競合)ステータスコードは、ターゲットリソースの現在の状態との競合のために要求を完了できなかったことを示しています。このコードは、ユーザーが競合を解決し、リクエストを再提出できる状況で使用されます。サーバーは、ユーザーが競合のソースを認識するのに十分な情報を含むペイロードを生成する必要があります。
と
500(内部サーバーエラー)ステータスコードは、サーバーがリクエストを満たすことを妨げる予期しない条件に遭遇したことを示します。
私たちは伝統的に500は未解決の例外のようであると考えてきましたが: -
一貫して適用されて設計されている限り、自分のステータスコードを発明するのは不合理ではないと思います。
このデザインは対処しやすいです。
PUT { membership add command } /accounts/groups/memberships/instructions/1739119
その後、APIを設計して、常に命令を作成することに成功することができます。 作成された201 そしてa 位置 ヘッダーと命令に関する問題は、その新しいリソース内に保持されます。
投稿は、新しい場所に最後に入れられたものに似ています。投稿では、メッセージのあらゆる種類のサーバー処理が可能になり、「アクションが正常に失敗した」などのデザインが開きます。
おそらく、あなたはすでにこれを行うAPI、ウェブサイトを書いたでしょう。支払いフォームを投稿すると、クレジットカード番号が間違っていたため、拒否されました。
投稿がある場合、拒否メッセージとともに200か201を返すかどうかは、新しいリソースが作成され、別の場所で入手できるかどうかによって異なります。
そうは言っても、私はデータフィールドを更新するだけでなく、ルールと処理を呼び出すアクションとものを更新するか、予想される障害の可能性が高いAPIを設計する傾向があり、命令を投稿するように設計することができます。形。