web-dev-qa-db-ja.com

論理エラーのHTTP 400(不正な要求)、不正な形式の要求構文ではありません

HTTP/1.1仕様(RFC 2616) には、 ステータスコード400、不正な要求(§10.4.1) の意味について次のように記述されています。

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

最近のHTTPベースのAPIの中には、リクエストでsyntaxエラーではなくlogicalを意味する400を使用する一般的な慣行があるようです。私の推測では、APIは 4 (クライアント誘導)と 5 (サーバー誘導)を区別するためにこれを行っていると思います。 400を使用して非構文エラーを示すことは容認できますか、それとも間違っていますか?受け入れられる場合、RFC 2616に注釈付きのリファレンスがあり、400の使用目的に関する詳細な情報が提供されていますか?

例:

63
Atif Aziz

この時点で、RFC 2616を置き換えて廃止することを目的とした HTTPbis 仕様の最新ドラフト states

400(Bad Request)ステータスコードは、受信した構文が無効、無意味、またはサーバーが処理しようとするものに対する制限を超えているため、サーバーが要求を処理できないか、処理しないことを示します。

この定義は、もちろん変更される可能性がありますが、論理エラーに400で応答するという広く使用されている慣行を承認しています。

15
Jon

ステータス422( RFC 4918、セクション11.2 )が思い浮かびます:

422(Unprocessable Entity)ステータスコードは、サーバーがリクエストエンティティのコンテンツタイプを理解し(したがって415(Unsupported Media Type)ステータスコードが不適切)、リクエストエンティティの構文が正しいことを意味します(したがって、400(Bad Request )ステータスコードは不適切です)が、含まれている指示を処理できませんでした。たとえば、XML要求本文に整形式(つまり、構文的に正しい)であるが、意味的に誤ったXML命令が含まれている場合、このエラー状態が発生する可能性があります。

62
Julian Reschke

HTTPbisは、論理エラーもカバーするように、400 Bad Requestのフレージングに対処します。したがって、400には422が組み込まれます。

から https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
「クライアントエラー(たとえば、不正な構文)のために、サーバーはリクエストを処理できないか、処理しません」

6
Andrei Neculau

論理エラーを表すためにも400を使用していますが、この場合、仕様の読み方のために400を返すのは間違っていると言わざるを得ません。私がそう思う理由は次のとおりです。論理エラーは、別のエンティティとの関係が失敗したか満たされていない可能性があり、他のエンティティに変更を加えると同じものが後で渡される可能性があることです。その従業員が存在しない場合(論理エラー)、その従業員を部門のメンバーとして(完全に仮説的に)追加しようとするようなものです。従業員が存在しないため、従業員をメンバーリクエストとして追加できませんでした。しかし、従業員がシステムに追加された後、同じ正確な要求が渡される可能性があります。

ちょうど私の2セント...私たちは最近RFCの言語を解釈する弁護士と裁判官が必要です:)

ありがとう、ヴィッシュ

2
Vish

HTTPレベルでの実際のリクエスト(リクエスト行、ヘッダーなど)であっても、リクエストに間違ったデータが含まれていると、構文エラーであると主張できます。構文的に有効です。

たとえば、Restful Webサービスがapplication/vnd.example.com.widget+xmlのカスタムXMLコンテンツタイプのPOSTを受け入れると文書化されており、代わりに何らかの意味のないプレーンテキストまたはバイナリファイルを送信する場合、構文エラーとして扱うのは理にかなっているようです-リクエスト本文が予期した形式ではありません。

ただし、これをバックアップする公式の参考文献は知りませんが、いつものように、RFC 2616の解釈に問題があるようです。

更新:RFC 7231§6.5.1 :の修正された文言に注意してください

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

廃止された RFC 2616§10.4.1 よりも、この議論をサポートしているようです。

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

2
Day

On Java EEサーバーは、URLが存在しない「web -application」を参照している場合、400を返します。それは「構文エラー」ですか?構文エラーの意味に依存します。はいと言うでしょう。

英語の構文規則では、品詞間の特定の関係を規定しています。たとえば、「ボブはメアリーと結婚します」というパターンは{名詞+動詞+名詞}というパターンに従っているため、構文的に正しいです。 「ボブ結婚メアリー」は構文的に間違っていますが、{名詞+名詞+名詞}。

単純なURLの構文は{protocol +:+ // + server +:+ port}です。これによると、「 http://www.google.com:8 」は構文的に正しい。

しかし、「abc://www.google.com:80」はどうですか?まったく同じパターンに従っているようです。しかし、実際には構文エラーです。どうして? 'abc'はDEFINEDプロトコルではないためです。

要点は、400の状況があるかどうかを判断するには、文字とスペースと区切り文字を解析する以上のことを必要とすることです。また、有効な「品詞」とは何かを認識しなければなりません。

1
Panu Logic

これは難しいです。

すべきだと思う。

  1. クライアントがリクエスト、ヘッダー、またはボディを変更する権限を持っている場合にのみ、4xxエラーを返します。これにより、同じ意図でリクエストが成功します。

  2. 予想される突然変異が発生していない場合、つまり、DELETEが発生しなかった、またはPUTが何も変更しなかった場合に、エラー範囲コードを返します。ただし、POSTは、新しい場所でリソースを作成するか、単にペイロードを処理するために使用する必要があると仕様が規定しているため、より興味深いものです。

Vishの回答の例を使用すると、要求が従業員Priyaを部門Marketingに追加するつもりであるが、Priyaが見つからないか、彼女のアカウントがアーカイブされている場合、これはアプリケーションエラーです。

リクエストは正常に機能し、アプリケーションルールに到達し、クライアントはすべてを適切に実行し、ETagは一致しましたなど。

HTTPを使用しているため、リソースの状態に対する要求の影響に基づいて応答する必要があります。そして、それはあなたのAPIデザインに依存します。

おそらくあなたはこれを設計しました。

PUT { updated members list } /marketing/members

成功コードを返すことは、リソースの「置換」が機能したことを示します。リソースに対するGETは変更を反映しますが、反映しません。

そのため、適切なネガティブHTTPコードを選択する必要があります。コードはアプリケーションではなくHTTPプロトコルを強く対象としているため、それは難しい部分です。

公式のHTTPコードを読むと、これら2つは適切に見えます。

409(競合)状態コードは、ターゲットリソースの現在の状態と競合するため、要求を完了できなかったことを示します。このコードは、ユーザーが競合を解決してリクエストを再送信できる状況で使用されます。サーバーは、ユーザーが競合の原因を認識するのに十分な情報を含むペイロードを生成する必要があります。

そして

500(内部サーバーエラー)ステータスコードは、サーバーが予期しない状態に遭遇したために、要求を処理できないことを示しています。

私たちは伝統的に500は未処理の例外のようなものだと考えてきましたが:-/

一貫して適用および設計されている限り、独自のステータスコードを発明することは不合理ではないと思います。

この設計は対処が簡単です。

PUT { membership add command } /accounts/groups/memberships/instructions/1739119

その後、常に命令の作成に成功するようにAPIを設計できます。これは201 CreatedおよびLocationヘッダーを返し、命令に関する問題はその新しいリソース内に保持されます。

POSTは、新しい場所への最後のPUTに似ています。 POSTを使用すると、メッセージのあらゆる種類のサーバー処理が可能になり、「アクションが正常に失敗しました」などのメッセージが表示されます。

おそらく、これを行うAPIであるWebサイトをすでに作成しているでしょう。お支払いフォームをPOSTしましたが、クレジットカード番号が間違っていたため、正常に拒否されました。

POSTでは、拒否メッセージとともに200または201を返すかどうかは、新しいリソースが作成され、別の場所でGETに使用できるかどうかによって異なります。

以上のことから、必要なPUTが少ないAPIを設計する傾向があります。おそらく、データフィールドを更新するだけで、アクションやルールと処理を呼び出すアクションや、予想される失敗の可能性が高いものは、POST指示書。

1
Luke Puplett