サーバーのビジネスロジックエラーを表すためにHTTPステータスコードを使用する必要がありますか?


20

私は、クライアント(ブラウザーのJS)がサーバーと通信するためのAPI設計との岐路にあります。HTTP 409 Conflictを使用して、安全ロックが有効であるためにアクションが失敗することを表します。satefyロックは、開発者がお客様の生産システムを誤って変更することを防ぎます。特定のAPI呼び出しが失敗した理由を示すために、クライアントで409をもう少し優雅に処理するように任されました。

私の解決策は、409が原因で何かが失敗したときにクライアントに通知を表示するAJAX呼び出しの失敗ハンドラーをラップすることでした-これはすべて問題なく、同じメカニズムを使用する他の4XXおよび5XXエラーと一緒にうまく機能します。

ルートハンドラーの1つがビジネスロジックエラーに遭遇したときに409で応答するという問題が発生しました-私のAJAXラッパーは安全ロックがオンであることを報告しますが、クライアントの既存の障害ハンドラーは問題が何に基づいている(考えている)かを報告します応答の。簡単な解決策は、安全ロックを表すために使用するハンドラーの応答またはステータスコードを変更することです。

それが私の岐路に私を連れて行きます:HTTPステータスコードはビジネスロジックエラーを表すためにも使用されるべきですか?この質問は、私が直面しているのと同じ問題に対処しますが、あまり注目を集めませんでした。リンクされた回答で示唆されているように、ビジネスロジック内の障害を表すために適切なボディでHTTP 200 OKを使用することに傾倒しています。

ここに強い意見はありますか?誰かがこれを失敗を表す間違った方法だと私に納得させることができますか?


3
簡単な意見を回答として投稿するのをためらいます。つまり、ビジネスエラーを表すためにHTTPステータスコードを使用することは通常避けます。これらは、クライアントとサーバー間の通信のステータスのみに関係する必要があります。検証またはビジネスロジックエラーを返すのに適したステータスコードは次のとおり400 Bad Requestです。この分離の理由は、将来のシステム、開発者、またはドキュメントの読者が、世界標準からの逸脱によって混乱する可能性があるためです。
イヴォクーマンズ

@IvoCoumans:これに答えてください^私はそれを支持することができました。400 Bad Request包括的なHTTPコードは、クラスとしてビジネスロジックエラーをカバーするのに最適だと思われます。
9000

個人的な好みですが400 Bad Request、データがない場合や読み取り/解析できない場合に使用する傾向があります。すなわち、リクエストデータ自体が何らかの形で悪いです。
ケイシースピークマン

「ビジネスロジックエラー」の意味を詳しく説明してください。それは非常にあいまいです。(正しい)データ検証チェックに従って無効な入力、他の時点では有効であるが現在の状態では無効な入力、または有効な入力を拒否するビジネスロジックのバグを意味しますか?
jpmc26

@ jpmc26一般的な質問だったので、意図的に曖昧にしていました。サーバーはリクエストをうまく処理しましたが、クエリ/アサーションが意味をなさないと判断しました。
ジョーシャナハン

回答:


19

Kaseyが主要なポイントをカバーしています。

任意のWeb APIの重要なアイデア:ドメインをドキュメントストアのように適合させること。GET / PUT / POST / DELETEなどは、すべてドキュメントストアとやり取りする方法です。

したがってどのコードを使用するかについて考える方法は、ドキュメントストアでの類似操作が何であるか、そしてその失敗がこのアナログでどのように見えるかを理解することです。

2xxは完全に不適切です

ステータスコードの2xx(成功)クラスは、クライアントの要求が正常に受信され、理解され、受け入れられたことを示します。

5xxも不適切です

ステータスコードの5xx(サーバーエラー)クラスは、サーバーがエラーを認識していることを示します

この場合、サーバーは間違いを犯していません。現時点では、そのリソースをそのように変更することは想定されていません。

ビジネスロジックエラー(ビジネス不変条件では現時点で提案された編集が許可されていないことを意味する)は、おそらく409

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

この最後のビットに注意してください-409応答のペイロードは、何が間違っているかについて消費者に情報を伝える必要があり、理想的には競合を解決するのに役立つリソースに消費者を導くハイパーメディアコントロールを含める必要があります。

私の解決策は、409が原因で何かが失敗したときにクライアントに通知を表示するAJAX呼び出しの失敗ハンドラーをラップすることでした-これはすべて問題なく、同じメカニズムを使用する他の4XXおよび5XXエラーと一緒にうまく機能します。

そして、これを問題として指摘します。クライアントでの実装では、ステータスコードが問題を定義するのに十分であると想定していました。代わりに、クライアントコードはペイロードを確認し、そこで利用可能な情報に基づいて行動する必要があります。

つまり、結局のところ、ドキュメントストアがそれを行う方法

409  Conflict

your proposed change has been declined because ${REASON}.  
The following resolution protocols are available: ${LINKS[@]})

a 400 Bad Requestと同じアプローチも受け入れられます。「おおよそ」は「リクエストに問題がありました」に変換されます。どのステータスコードが最適かわからないので、ここで説明します。詳細については、ペイロードをご覧ください。」

422を使用します。入力は有効であるため、400は使用するのに適切なエラーコードではありません

WebDAV仕様にはこの推奨事項が含まれています

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

私はそれが完全に一致するとは思わない(400代替としていくつかの疑問を投げかけることに同意するが)。私の解釈は、422「あなたは間違ったエンティティを送信しました」という意味ですが、「409間違った時間にエンティティを送信した」ということです。

別の言い方422をすれば、リクエストメッセージが単独で考慮される問題を409示します。リクエストメッセージがリソースの現在の状態と競合することを示します。

422のBen Nadalの議論は検討するのに役立つかもしれません。


5
あなたはドメインをドキュメントストアのように適応させています」-私は人々がこれを読んで、RESTを決定する(または反対する)にすべての結果と影響を完全に理解するのを見てみたいです。本当に。
JensG

「ビジネスロジックエラー」は「無効な入力」のように聞こえますが、より具体的なエラーコードはないため、通常は通常は400です。無効な入力でない場合、サーバーにはバグがあり、500が適切です。あなたの答えは、「ビジネスロジックエラー」の性質について過度に推測しているようです。
jpmc26

入力は有効なので、400は使用するのに適切なエラーコードではありません
Konrad

19

私の経験では、HTTPエラーコードはビジネスエラーを表すには不十分です。ただし、これらはエラーのクラスを表すのに役立ちます。

そのため、エラーのカテゴリにHTTPエラーコードを使用することをお勧めしますが、ビジネスロジックの障害には特定のエラー(409 Conflict ... 200 OKはここでは誤解を招く可能性があります)を選択し、特定のビジネスエラーを示すデータを応答に含めます。一部のブラウザはカスタムステータステキストを無視するため、これがステータステキストではなく、応答コンテンツの一部であることを確認してください。使用したい言語には、メッセージを表すのに便利なユニオン型があります。ただし、エラーの場合に文字列定数を定義することもできます。

// error with text response
409 Conflict "safety_lock_engaged"
409 Conflict "customer_not_eligible_for_selected_discount"
// warning with JSON response
202 Accepted { "backorderedProductIds": [ 37, 476 ] }

400を超える4xxステータスコードには、非常に具体的な意味があります。ケースが他のケースで特にカバーされていない場合は400を選択してください。
jpmc26

@ jpmc26このようにステータスコードを使用しない場合、それらは使用されません。しかし、あなたの答えでそれらを正しい方法で使ってください。
ケイシースピークマン

ある意味では、あなたは正しい。それらは決して使用されません。特定のコードに選択された意味は、ほとんどのアプリケーションの非常に一般的なユースケースではないようです。大丈夫。キャッチするコードを決して書かない例外もたくさんあります。
jpmc26

@ jpmc26まあ、例外は従うべき最大のモデルではありません。しかし、確かに、先に行きます。
ケイシースピークマン

特定の例外タイプに対してスローまたはキャッチしないことは、特定のHTTPコードまたはその他のエラーコードを使用しないことと類似しています。これは明らかだと思いました。例外モデルが「最高」であるかどうかは、その点とまったく無関係です。
jpmc26

5

一般に、特定のビジネスロジックエラーを表すためにHTTPステータスコードを使用することは避けます。これは、それらがすでに世界的な標準によって定義されているセマンティックな意味を持っているためです。他のシステム、新しい開発者などは、標準の逸脱によって混乱します。

最近の同様の研究で私が見つけたのは400 Bad Request、検証エラーなどの場合に使用することが一般的に受け入れられているということです。このように、すべてのビジネスロジックエラーに対して1つのステータスコードを使用します。

ちなみに、409編集中にリソースが変更され、再度保存しようとしたときに使用する必要があります。


4

「Bad Request」を使用して、違反したビジネスルールのIDと、応答の本文に関する詳細を含めることができます。


これが反対票を投じられたのはなぜかわかりません。これは、企業がビジネス例外を返す方法です。
スカドーシュ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.