一般的な失敗したリクエスト(エラーではない)に対する適切なHTTPステータスコード応答は何ですか?


109

保存したクレジットカードを使用した注文など、ユーザーとのさまざまなやり取りを処理するRESTful APIを作成しています。

注文が成功した場合は200 OKを返し、注文リクエストの形式が無効または無効な場合は400 Bad Requestを返します。しかし、注文の実際の処理中に問題が発生した場合はどうすればよいですか?

  1. ユーザーリソースのサーバーへのクライアントPOSTS注文。ユーザーが存在しない場合は、404 Not Foundが返されます。
  2. 注文の形式と情報が検証されます。無効な場合、400 Bad Requestが返されます。
  3. 注文が処理されました。注文が成功すると、注文に対して201 Createdが返されます。予期しないエラーが発生した場合、500サーバーエラーが返されます。

最後のステップは問題です。他の理由で注文が完了しなかった場合はどうすればよいですか?考えられるシナリオは次のとおりです。

  • 商品は売り切れです
  • ユーザーの最大注文数に達しました
  • クレジットカード決済失敗(資金不足等)

これは、400と500のどちらにも適しているとは思えません。適切なコードがない場合、400と見なすことができます。ビジネスルールによれば、リクエストは無効でした。正確ではないようです。

編集:同じトピックに関するこの既存のディスカッションも見つかりました。そこにあるすべての回答は、このタイプの違反にステータスコードを使用することを示しているようです。400、409、または422の拡張機能を使用することについての議論もあります。


8
検証エラーには「422 unprocessable entity」が好きです。そして、あなたの上記の例のためにそれを使用して、実際のビジネスの問題と応答にメッセージを含める「製品が完売された」と、おそらく、クライアントのニーズ場合は、プログラムに独自の「コード」を追加し、応答に基づいて、異なる決定を下すだろう
house9

422に
進む前に、

回答:


90

ビジネスルールには400を使用する必要があります。注文が受理されなかった場合は2xxを返さないでください。HTTPはアプリケーションプロトコルです。決して忘れないでください。2xxを返すと、本文で送信した情報に関係なく、クライアントは注文が受け入れられたと見なすことができます。


以下からのRESTful Webサービスのクックブック

一部のWebサービスでよくある間違いの1つは、成功を反映するステータスコード(200から206および300から307までのステータスコード)を返すが、エラー状態を説明するメッセージ本文を含むことです。これを行うと、HTTP対応ソフトウェアがエラーを検出できなくなります。たとえば、キャッシュは成功した応答として保存し、クライアントが成功した要求を行うことができる場合でも後続のクライアントに提供します。

4xxと5xxのどちらにするかはあなたにお任せしますが、エラーステータスコードを使用する必要があります。


1
このアプローチと他のアプローチの例や参考資料はありますか?1つはアプリケーションプロトコルとしてのHTTPの観点から、もう1つは厳密に転送の目的のためであるという観点から、あなたとWidorの両方の答えは理にかなっています。仕様では、これを「アプリケーションレベルのプロトコル」と定義していますが、これは少しあいまいです。これを研究しているとき、私はウェブの周りの見方と例の両方を見てきました。
Raelshark

信用できる。
Young Hyun Yoo

2
「ビジネスルールには4xxを使用する必要がある」という意味ですか?
Yawar、

28

クライアントがリクエストを変更してエラーを回避できる場合、クライアントエラーには4xxを使用する必要があります。クライアントが実際に回避できないサーバーエラーには5xxを使用します。

売り切れの商品はサーバーエラーになります。クライアントは、エラーを回避するために何らかの方法で要求を変更することはできません。別の製品に切り替えることができますが、それは新しい要求ではないでしょうか?

ユーザーの最大注文制限に達したこともサーバーエラーです。クライアントがそのエラーを回避するためにできることは何もありません。

クレジットカード取引の失敗はクライアントエラーです。クライアントは、エラーを回避するために、別の支払い方法またはクレジットカード番号でリクエストを再送信できます。


6
注文制限に達した場合、クライアントはそのことをユーザーに警告し、要求を適切に変更させてはいけませんか?4xxエラーのようです。売り切れ商品も同様です。5xxエラーは、システムが何らかの方法で故障したために発生するエラーを対象としており、ビジネスルールによって許可されていないアクションを対象としています。
carlin.scott

7
上記のコメントに同意します。5xxエラーは、サーバーに問題がある場合に発生します。ビジネスルールの4xxエラー。
Merc

21

エラータイプ:

4×× Client Error

エラーコード:

422 Unprocessable Entity

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

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

https://httpstatuses.com/422


16

この質問が古いことは知っていますが、今日も同じ質問を思いつきました。ユーザーがクレジットを使い果たした場合、REST APIはどのステータスコードを返す必要がありますか?

私は傾く傾向があります402 Payment Required

ウィキペディアによると:

将来の使用のために予約されています。当初の目的は、このコードが何らかの形のデジタルキャッシュまたはマイクロペイメントスキームの一部として使用される可能性があることでしたが、実際には発生せず、このコードは通常は使用されません。Google Developers APIは、特定の開発者が1日のリクエスト制限を超えた場合にこのステータスを使用します。

そして確かに彼らはそうします

PAYMENT_REQUIRED(402)

  • デベロッパーが設定した1日の予算の上限に達しました。
  • リクエストされた操作には、割り当てが許可するよりも多くのリソースが必要です。操作を完了するには支払いが必要です。
  • 要求された操作には、認証されたユーザーからの何らかの支払いが必要です。

これは最もよく考えられた論理的な答えです。
GTodorov

5

いかが424 Failed Dependencyですか?仕様では次のように説明しています。

要求されたアクションが別のアクションに依存していて、そのアクションが失敗したため、リソースでメソッドを実行できませんでした。

しかし、この定義もあります

ステータスコード424はWebDAV標準で定義されており、クライアントが実行していることを変更する必要がある場合のためのものです。ここではサーバーで問題は発生していません。

注文を作成することになっている内部アクションがあり、残高を差し引くこと、および完全に正当な理由にもかかわらず、これらのアクションの1つが失敗したことをクライアントに伝える(またはふりをする)ことができ、それが要求が失敗した理由です。

私の知る限り、「アクション」はかなり広義の用語であり、在庫不足、クレジット不足、倉庫パーティーの夜など、さまざまな状況で使用できます。


別のオプションがあります422 Unprocessable Entity

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

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

在庫切れの商品をリクエストしようとしたり、クレジットが不足したりすると、セマンティックレベルでのミスと見なされる場合があります。

MozDev は、これはクライアント側の間違いを示していると具体的に言っています:クライアントは変更なしでこのリクエストを繰り返すべきではありません。

ループバック4 、入力の検証に失敗すると 422を使用します。


おそらく、不十分な在庫または倉庫パーティーの夜は一時的な状態と見なされる可能性があるため、要求は後で再試行できます。その状況は、503 Service Unavailable

サーバーは現在、一時的な過負荷または定期的なメンテナンスのために要求を処理できません。これは、多少の遅延後に緩和される可能性があります。

サーバーはRetry-Afterヘッダーフィールドを送信して、リクエストを再試行する前にクライアントが待機する適切な時間を提案する場合があります。


それらのどれも支払いに関連していません。私は前の回答から402で行きます!
GTodorov

2

400はすべてのビジネスシナリオに使用できるとは思いません。基本的なデータ入力検証に使用できます。それを超えると、他のビジネスロジックをこのエラーコードに組み込むのに時間がかかる場合があります。これによって処理されるエラーは、ほとんどの場合、開発者がクライアントのコーディング中に発生する可能性のある設計時エラーです。

すべてのパラメータが正しく、たとえば、ユーザーアカウント番号をリクエストに渡しているとします。

したがって、リクエストはもはや悪いリクエストではなくなり、サーバーはリクエストを受け入れることができます。しかし、現在、利用可能な新しい情報に基づいてリクエストを実行することは拒否されています-アカウントには十分なバランスがありません。

これらのシナリオでは、適切なエラーメッセージと共に403を使用することをお勧めします。

その他の考えられるエラーコードは、409の競合である可能性があります。ただし、これはリソースが一貫した状態にあるシナリオで使用されます。


-1

406で行きNot Acceptableます。

ここに4xxリストがあります:

const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
const HTTP_REQUEST_TIMEOUT = 408;
const HTTP_CONFLICT = 409;
const HTTP_GONE = 410;
const HTTP_LENGTH_REQUIRED = 411;
const HTTP_PRECONDITION_FAILED = 412;
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
const HTTP_REQUEST_URI_TOO_LONG = 414;
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
const HTTP_LOCKED = 423;                                                      // RFC4918
const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585

8
ステータスコード406の名前はそれ自体で正確に聞こえるかもしれませんが、各ステータスコードには信頼できるテキストによる説明があることに注意する必要があります。ステータスコード406の説明は、現在のケースには適しいません。たとえば、httpstatuses.com/406を参照してください。
Zero3

1
@ Zero3は正しいです。このコードは、クライアントから送信されたAcceptヘッダーとエンドポイントによって送信されたMediaTypeの間に不一致があるため、応答タイプが許容できないことを意味します(例:application / jsonとtext / plain
Gregor)。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.