パラメーターが構文的に正しいが、ビジネスルールに違反している場合、HTTP 400(Bad Request)ステータスを返す必要がありますか?


56

パラメーターとして整数を使用するRESTエンドポイントがあるとします。

/makeWaffles?numberOfWaffles=3

この場合、負の数のワッフルを作ることができないため、この数を正にしたいです(そして、0のワッフルを要求するのは時間の無駄です)。したがって、正の整数を含まない要求を拒否したいと思います。また、最大の整数を超えるリクエストを拒否したい(今はMAX_INTEGERであるとしましょう)。

誰かが非正数のワッフルをリクエストした場合、HTTP 400(Bad Request)ステータスを返すべきですか?私の最初の考えはイエスです:それは私がリクエストを完了するための有効な数字ではありません。ただし、RFCでは、ビジネスルールをスローする理由として言及していません。

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

ビジネスルールは、これら3つの例のいずれにも該当しません。これは構文的に正しく、適切にフレーム化されており、不正なリクエストルーティングではありません。

パラメータが構文的に正しいが、ビジネスルールに違反している場合、HTTP 400(Bad Request)ステータスを返す必要がありますか?または、返すのに適切なステータスがありますか?



回答:


38

これは素晴らしい質問であり、HTTPリターンコードの歴史的背景(および一見矛盾する定義)を考えると、非常に重要です。この質問に対する答えの中にも、矛盾する定義があります。これは時系列に移動することで明確になります。

RFC 2616(1999年6月)

10.4.1 400 Bad Request

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

このRFCの時点で、このステータスコードは構文的に無効なリクエストにのみ適用されます。セマンティック検証のステータスコードにギャップがありました。したがって、RFC 4918が登場すると、新しいコードが生まれました。

RFC 4918(2007年6月)

11.2。422処理できないエンティティ

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

422 4xxステータスコードの元の仕様のセマンティック検証のギャップを埋めるために、処理不能なエンティティが作成されました。しかし、もう1つの関連RFCが2014年に登場し、400を一般化して構文に固有ではなくなった

RFC 7231(2014年6月、RFC 2616を明示的に廃止)

6.5.1。400不正な要求

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

422の説明では、400が不適切である理由は、400(RFC 2616以降)が不正な要求構文に対してのみ返されるためであると述べられていることに注意してください。ただし、RFC 7231の時点で、厳密な構文エラーの定義は400には適用されなくなりました

手元の質問に戻ります:422は技術的に具体的ですが、このコンテキストを考えると、APIパラメーターのセマンティック検証に400または422が使用されていることがわかります。422の定義は現時点では技術的に古いため、自分のAPIで422を使用することをためらっています(ただし、422がどこで公式に認識されているかはわかりません)。Franの回答で言及されている422の使用を推奨する記事は、RFC 7231がHTTP 400を明確にした2年前の2012年に書かれました。


42

少なくとも私の読書では、悪いリクエスト(400)は、「何かが根本的に間違っているので、あなたのリクエストを処理することすらできない」ということを意味しているため、最初の答えを読んで本当に同意しませんでした。そして 、422を返すことを主張するこの投稿を見つけました。

IETFから

422 Unprocessable Entity(WebDAV; RFC 4918)要求は整形式でしたが、セマンティックエラーのために追跡できませんでした

リクエストは整形式ですが、検証ルールに合格していないため、これはより適切な応答のようです。


5
「400は構文が悪い、422は意味が悪い」と説明されていると聞いたことがあります。
cbojar

33
すべてのx00コードは「catch all」汎用コードです。400は不適切ではなく、具体性が低くなります
ジャック

1
良い答えですが、@ GoFreeによって与えられた回答者は私にとってより理にかなっています。
エワートン

2
誰もが知っているコードを返すための本当に強力なケースがあります。絶対に誰もが422を調べる必要がありますが、ほとんどの人はそれをどうしたらいいかわからないでしょう。
シルバナール

8

はい、エンドポイントの暗黙の契約に従わない入力は「クライアントエラーであると認識されるもの」であり、400を返す必要があります。

これの例外は、ビジネスルールがセキュリティ関連である場合です(その401 Unauthorized場合、またはそれ403 Forbiddenより優れています)。あるいは、400を送信すると何かの存在に関する情報が漏洩する404 Not Found場合、aの方が適切かもしれません。


8

いいえ、すべきではありません。HTTPコードは、アプリケーションのHTTPレイヤー用です。ビジネスルールはまったく異なる層であり、アプリケーション固有であるため、独自の「プロトコル」を作成する必要があります。

黙示録が発生し、HTTPプロトコルからPigeonsの使用に切り替える必要があると想像してください。ハトにはリターンコードがないため、ビジネスレイヤーを変更してそれに対応する必要があります。ただし、ビジネスは実際にはまったく変更されていないため、ビジネスレイヤーを変更する必要はありません。これらの2つのレイヤー(トランスポートとビジネス)の間の密結合を示しています。

質問に戻ります。あなたがすべきことは、リクエストで何が起こったのかを説明するボディとともに「200 OK」を返すことです。仕様には次のように明記されています。

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1

200 OK

要求は成功しました。応答で返された情報は、要求に使用される方法に依存して、例えば、

アクションの結果を説明または含むエンティティをPOSTします。

HTTPリクエストは成功しましたか?はい。Webサーバーはそのリクエストをどう処理するかを知っています(たとえば、アプリケーションのサーバー部分に渡します)。次に、Webサーバーはこの要求をアプリケーションのサーバー部分に渡します。サーバー部分はPOSTされたデータを取得して処理し(ケースで検証し)、アプリケーションのクライアント部分に通常の応答(HTTP応答の本文)を返します。 。アプリケーションのサーバー部分からのこの回答は、「素晴らしい、送信したデータは有効です」または「申し訳ありませんが、送信したデータは無効です」のいずれかです。そして、答えが何を意味するかを理解することは、アプリケーションのクライアント側の責任です。

PS:「400 Bad Request」は、Webサーバーがそれから何を望んでいるかを理解しなかったことを意味します。これは、アプリケーションのサーバー部分がリクエストを受信しなかったことを意味します。または、少なくともそれが意味することです:-)

編集:あなたはPOSTではなくGETリクエストをしていることに気付きました。GETはアプリケーションの状態を変更すべきではないため、これは悪い考えです。GETは、サーバーからデータを単に取得することになっています。ただし、リクエストでは実際にアプリケーションの状態を変更しているので、実際にはPOSTを使用する必要があります。


1
はい、その場合に404​​を返しても問題ありません。サーバーは常に200 OKを送信し、本文に説明を含める必要があるとは言っていません。
GoFree

これまで見てきたより良い説明。この同じ質問があり、すべての言葉は私とあなたとは違うと思うようです@GoFree
Ewerton

@GoFreeこれは、APIデザインを再考するための本当に良い答えです。しかし、REST APIを使用するときに、ビジネスルールレイヤーの重要な部分としてHTTPとその応答コードを使用するのは事実ではありませんか?
トーマス・ラウリア

1
@Thomas Lauria RESTFUL APIの適切な実装はまだ見ていません。ただし、REST APIは今日の流行語であるため、すべての企業がその背後にある概念を実際に理解することなく、それを使用する必要があります(テクノロジではなく、単語)。はい、それはどこでも間違った方法で使用されています。プログラマーが通常作成するのはREST APIではなく、HTTP APIまたはAPI OVER HTTPです。実際、数少ない優れたRESTFUL実装の1つはHTTP自体です:)
GoFree

1
使用するアプリケーションは、等高すぎたり低すぎたりまたは欠落入力値、在庫切れの製品、などの任意のビジネス・レベルのエラーを記述するレスポンスボディに「エラー」フィールドが含まれている場合、200 OKは、特に論理的である
ローランド

-3

すべてが同意するかどうかはわかりませんが、409-Conflictを使用しています。多くの状態は409がシステム状態と矛盾していると述べていますが、許容範囲外のデータ値の矛盾はリクエスターによって修正可能であり、409の許容可能な使用法であるという解釈を受け入れました。は正しく形成されていますが、要求どおりに処理できません。ただし、多数の返信を実装したくない場合は、400を指定するだけで十分です。


5
409は、それが(例えば、てETagを使用して)同時書き込みをブロックするためだ、「あなたはこの中に入れしようとしている状態は、別のクライアントが、この中に入れしようとしている状態と競合している」という意味
ジャック・
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.