REST APIエラーが良い習慣を返す[終了]


623

REST APIからエラーが返されるようになると、良い習慣に関するガイダンスを探しています。私は新しいAPIに取り組んでいるので、今はどの方向にでも進むことができます。現在のコンテンツタイプはXMLですが、将来はJSONをサポートする予定です。

たとえば、クライアントが新しいリソースを追加しようとしたが、ストレージクォータを超えたなど、いくつかのエラーケースを追加しています。HTTPステータスコード(認証は401、承認は403、プレーンなリクエストURIは404)を使用して、特定のエラーケースをすでに処理しています。祝福されたHTTPエラーコードを調べましたが、アプリケーション固有のエラーを報告するのに適切な範囲である400〜417の範囲はありません。したがって、最初は200 OKと特定のXMLペイロードでアプリケーションエラーを返したくなりました(つまり、さらに料金を払えば、必要なストレージを取得できます)。ホラーに肩をすくめる)。その上、エラーレスポンスを別個のケースに分割しているような気がします。いくつかはhttpステータスコードドリブンで、他はコンテンツドリブンです。

では、業界の推奨事項は何ですか?グッドプラクティス(理由を説明してください!)と、クライアントの視点から、REST APIでどのようなエラー処理を行うと、クライアントコードの処理が容易になりますか?


7
明確にするために:どの特定のHTTPステータスコードを返すかにはあまり関心がありませんが、ペイロードエラーをHTTPステータスコードと組み合わせるのに適したRESTプラクティスなのか、それともペイロードのみに依存する方が良いのか、です。
Remus Rusanu

3
REST API設計ハンドブックは、このトピックをかなりカバーしています。
Remus Rusanu

12
質問は意見を求めるのではなく、ガイダンス/推奨事項を求めるものであり、再度開いて参照として使用する必要があります。2009年に作成された2016年の質問の
締めくくり

4
ほとんど言及していませんが、HTTPエラーコードを使用すると、問題の主な原因に関する問題が発生する可能性があります。HTTPはトランスポートプロトコルであり、404はトランスポートレベルのURLに問題があったことを示す必要があります(例:パスが間違っているなど)。アプリケーションがそのIDでデータセットを見つけられない場合、これはアプリケーションレベルのエラー(トランスポートレベルのエラーではない)であり、restful httpステータスコードユーザーが示唆する404は誤った結論につながる可能性があります。一般的に、ステータスコードを使用する際にトランスポート層とアプリケーション層を混在させることは好きではありません。
SCI

回答:


220

したがって、最初は200 OKと特定のXMLペイロードでアプリケーションエラーを返したくなりました(つまり、さらに料金を払えば、必要なストレージを取得できます)。ホラーに肩をすくめる)。

リクエストに問題がない限り、200を返しません。よりRFC2616、200件の手段は、「要求が成功しました。」

(何らかの理由で)クライアントのストレージクォータを超えた場合、403(禁止)を返します。

サーバーはリクエストを理解しましたが、リクエストの実行を拒否しています。承認は役に立たず、リクエストは繰り返されるべきではありません。リクエストメソッドがHEADではなく、サーバーがリクエストが実行されなかった理由を公開したい場合は、エンティティで拒否の理由を説明する必要があります。サーバーがこの情報をクライアントに提供したくない場合は、代わりにステータスコード404(見つかりません)を使用できます。

これは、要求は問題なかったが、失敗したことをクライアントに伝えます(200では実行できないもの)。これにより、応答本文で問題(およびその解決策)を説明する機会も得られます。

他にどのような具体的なエラー状態を考えましたか?


6
詳細なエラーメッセージを本文に含めますか。XMLコード/文字列のペア?クライアントはこれにどのように対処するのが最適ですか?たとえば、C#WebRequestベースのクライアントが「Bad Request」または「Forbidden」をスローし、応答本文を提供しないことを知っています。
Remus Rusanu

18
403の本体には、エラーの詳細が含まれるはずです。クライアントが情報を利用する準備ができているかどうかは別の話です。この形式が他のすべてのペイロード(XML、JSONなど)の形式と同じであることが最も理にかなっています。
リッチアポダカ

1
...そして、詳細が403で返されない場合は、代わりに404 "can"を使用します(ただし、私にとって最良のオプションとは思えません)。
リッチアポダカ

6
404オプションは、許可されていないユーザーに知らせたくないアプリケーションの詳細を403が明らかにする可能性がある場合に使用します。たとえば、管理者以外のユーザーが管理者専用のURLにアクセスした場合、そのユーザーは不要になる可能性があります。管理者などにとって有効なURLであることを知る必要があります。ただし、この場合は、403が完全に適切です。
グレッグキャンベル

16
これはかなり役に立たない答えだと思います。より重要な側面は、ステータスを単独で使用するか、エラー情報をペイロードで返すか、またはその両方であるかなどです。次に、ペイロードに情報を追加する方法を考えます。使用される特定のステータスは、質問の特定の1つの側面のみに磨きをかけています。
Manachi、2015

584

APIの正しいHTTPエラーコードを選択するための優れたリソース:http : //www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

記事からの抜粋:

どこから始めれば:

ここに画像の説明を入力してください

2XX / 3XX:

ここに画像の説明を入力してください

4XX:

ここに画像の説明を入力してください

5XX:

ここに画像の説明を入力してください


1
422は特にWebDAV拡張です。私はそれがここにあるべきではないと思います。
マリオ

@Marioここで指定された条件に応じて422を返すのは、Ruby on Rails APIでは慣用的です。すでにそのアプローチに従って多くの良い。422の使用を何に置き換えますか?
Kelsey Hannan

通常の古い400
Andbdrew

ありがとうございました。「あなたはインターネットを激怒させていますか?」とはどういう意味ですか?
RoutesMaps.com 2018


87

主な選択は、HTTPステータスコードをREST APIの一部として扱うかどうかです。

どちらの方法でも問題なく機能します。厳密に言うと、RESTのアイデアの1つは、HTTPステータスコードをAPIの一部として使用することです(操作が成功した場合は200または201を返し、さまざまなエラーケースに応じて4xxまたは5xxを返します)。 、RESTポリスはありません。あなたがやりたいことができます。私は、「RESTful」と呼ばれる非常に悪質な非REST APIを見てきました。

この時点(2015年8月)では、APIの一部としてHTTPステータスコードを使用することをお勧めします。フレームワークを使用すると、以前よりもはるかに簡単に戻りコードを確認できるようになりました。特に、これまでよりも200以外のリターンケースと200以外の応答の本文を確認するのが簡単になりました。

HTTPステータスコードはAPIの一部です

  1. エラー条件に適合する4xxコードを慎重に選択する必要があります。サブコードと説明コメントを含むペイロードとして、rest、xml、または平文メッセージを含めることができます。

  2. クライアントは、HTTPレベルのステータスコードを取得できるソフトウェアフレームワークを使用する必要があります。通常は実行可能であり、必ずしも単純ではありません。

  3. クライアントは、通信エラーを示すHTTPステータスコードと、アプリケーションレベルの問題を示す独自のステータスコードを区別する必要があります。

HTTPステータスコードはAPIの一部ではありません

  1. アプリがリクエストを受け取って応答した場合、HTTPステータスコードは常に200になります(成功とエラーの両方のケース)。

  2. すべての応答には、「エンベロープ」または「ヘッダー」情報が含まれている必要があります。通常は次のようなものです:

    エンベロープバー:1.0
    ステータス:#好きなコードを使用してください。成功のためにコードを予約します。
    msg: "ok"#コードを反映する人間の文字列。デバッグに役立ちます。
    data:...#応答のデータ(存在する場合)。
  3. 応答のステータスは常に同じ場所にあり(サブコードは不要)、コードに制限がなく、HTTPレベルのステータスコードをフェッチする必要がないため、この方法はクライアントにとってより簡単になります。

これは同様のアイデアを持つ投稿です:http : //yuiblog.com/blog/2008/10/15/datatable-260-part-one/

主な問題:

  1. 必要に応じて後でAPIのセマンティクスを変更できるように、必ずバージョン番号を含めてください。

  2. 資料...


8
タイ。オプション2は、残りの服を着たSOAPのようですが...
Remus Rusanu

138
いいえ、200を介してすべてをトンネリングしても、まったく落ち着きはありません。仲介者が操作の結果を理解できないようにします。これにより、あらゆる形式のキャッシュが強制終了され、操作のセマンティクスが隠され、メッセージの内容を理解してエラーを処理し、自己完結型メッセージの制約に違反します。
SerialSeb

13
200でエラーの詳細を返すことはRESTfulではないかもしれませんが、それでも有用な答えです(「両方の方法が静止している」という注釈を無視する場合)...より大きな点は、RESTful APIが最適なオプションではない可能性があることです。 OP。
MB。

3
HTTPプロトコルでやりたいことは何でもできるという一般的な理解があるようですが、それでも「RESTy」であるというのは誤りです。それが書かれているものにプロトコルを使用することは、RESTのコアアイデアの1つです。したがって、ステータスコードプロトコルの一部である必要があります。
Ariel M.

ステータスコードの要点は、さまざまなプログラミング言語、フレームワーク、アプローチの間で共通の理解言語を提供することです。ステータスコードの意味は普遍的なものに近いものです。カスタムボディ(APIコンシューマーが学習する必要のあるカスタム構文により本質的に複雑さが増す)はそうではありません。
Kelsey Hannan

40

HTTP / 1.1 RFCで定義されているものよりも多くのステータスコードがあることに注意してください。IANAレジストリはhttp://www.iana.org/assignments/http-status-codesにあります。あなたがステータスコード507に言及した場合、正しいように聞こえます。


3
一見、「507 Insufficient Storage」は一見適切と思われるかもしれませんが、それは(かなり具体的な)WebDAV拡張として意図されており、一般的な「スペースが足りない」という意図ではないため、使用することはできません。例外。それでも、あなたはそれを使うことができると思います。
最大

1
いいえ、WebDAV固有ではありません。HTTPステータスコードのレジストリがあるのには理由があります。
Julian Reschke、2012年

26
私は507この目的に同意しません。私の解釈で507は、サーバーの空き容量が不足しているのではなく、アカウントの空き容量が不足しているのではありません。
Patrick

12
私はパトリックに同意します。5xxエラーは、サーバーで行うエラー用です。
Sean

10
418:「私はティーポットです」は、保管スペースが大きいのではなく(ティーポットが小さいように)少なすぎるため、スペースが不足していることを意味します。
Steve Konves、2013

22

他の人が指摘したように、エラーコードに応答エンティティを含めることは完全に許容されます。

5xxエラーはサーバー側であることを覚えておいてください。別名クライアントは、要求を通過させるために要求に何も変更できません。クライアントのクォータを超えた場合、それは間違いなくサーバーエラーではないため、5xxは回避する必要があります。


私は同意しません。クォータ超過はサーバーエラー(5xx)になります。理由は次のとおりです。クライアントのリクエストは有効で、クォータを下回ると成功し、400seriesが除外されます。
mikek3332002

4
しかし、サーバーは何も悪いことをしていません。
チャーリーシュライサー、2014

19

エラーには2種類あります。アプリケーションエラーとHTTPエラー。HTTPエラーは、AJAXハンドラーに問題がないことを知らせるためのもので、他の目的には使用しないでください。

5xx サーバーエラー

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates (RFC 2295 )
507 Insufficient Storage (WebDAV) (RFC 4918 )
509 Bandwidth Limit Exceeded (Apache bw/limited extension)
510 Not Extended (RFC 2774 )

2xx成功

200 OK
201 Created
202 Accepted
203 Non-Authoritative Information (since HTTP/1.1)
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status (WebDAV)

ただし、アプリケーションエラーをどのように設計するかは実際にはあなた次第です。たとえば、スタックオーバーフローはresponsedataおよびmessageプロパティを持つオブジェクトを送信します。私が信じる応答には、操作が成功したかどうか(通常は書き込み操作の場合)が含まれているか、trueまたはfalse示されています。データにはペイロード(通常は読み取り操作用)が含まれ、メッセージには追加のメタデータまたは有用なメッセージ(responseisの場合のエラーメッセージなど)が含まれますfalse


2
400は、クライアントアプリケーションの問題を示すのにも役立ちます。
ドルメン

19

私はこれがパーティーに非常に遅れていることを知っていますが、現在、2013年には、一般的な分散(RESTful)方式でのエラー処理をカバーするメディアタイプがいくつかあります。「vnd.error」、application / vnd.error + json(https://github.com/blongden/vnd.error)および「HTTP APIの問題の詳細」、application / problem + json(https:// tools。 ietf.org/html/draft-nottingham-http-problem-05)。


2
リンクをありがとう。draft-nottingham-http-problemが標準案として提案されました:datatracker.ietf.org/doc/rfc7807
seanf

9

同意した。RESTの基本的な考え方は、Webインフラストラクチャを使用することです。HTTPステータスコードは、HTTPペイロードを増やすことなく、パーティが互いに通信できるようにするメッセージングフレームワークです。それらはすでに応答のステータスを伝える確立されたユニバーサルコードであるため、真にRESTfulであるためには、アプリケーションはこのフレームワークを使用して応答ステータスを通信する必要があります。

HTTP 200エンベロープでエラー応答を送信することは誤解を招くものであり、クライアント(APIコンシューマー)がメッセージを解析するように強制します。これはおそらく非標準的な方法または独自の方法によるものです。これも効率的ではありません。「実際の」応答ステータスを理解するために、クライアントに毎回HTTPペイロードを解析させる必要があります。これにより、処理が増加し、レイテンシが追加され、クライアントがミスをする環境が作成されます。


3
成功した応答でも失敗した応答でも、おそらく応答を解析します。エラーの場合は、解析してエラーメッセージを取得します。エラー応答は一般に小さく、解析が高速です。エラー応答の解析を回避するために最適化を試みることについて心配する必要はないと思います。解析せずにエラー応答を破棄しますか?私の意見では賢明ではありません。
AgilePro 2015

3
200 OKを受け取った場合は、ビジネスルールによっては、解析しないことも選択できます。重要なのは、常に解析するかどうかではありません。ポイントは意図です-200 OKの意図は何ですか?200 OKでラップされたエラーメッセージを送信することで、インテントを損傷しています。
Kingz

1
「200 OKの目的は何ですか?」-トランスポート層の成功を示します。リクエストが正常に受信され、応答されました。HTTPとは関係のないアプリケーション固有の問題が発生しました。+++逆の言い方をすると:RESTの世界で404を送信することは、何かが見つからなかったことを意味します。URLが明らかに間違っているか、処理対象のリソースやその他のものが見つからなかった可能性があります。メッセージを解析しないとできません。IMHO RESTはレイヤーを統合するだけです。
maaartinus

融合は標準です。それはあなたの推論の行に合った対処するための構文を提供し、ビジネス層に集中することを可能にします。トランスポートの後半のステータス通信について合意しました-それはそもそも目的が何であったか-RESTはHTTPと同時に発明/提案されなかった-それは後で来て、単に状態とその変化を表すために既存のインフラストラクチャを使用することに決めました。
Kingz 2018年


5

プロトコルのセマンティクスに固執してください。成功した応答には2xxを使用し、エラー応答には4xx、5xxを使用します-ビジネスの例外などです。応答に2xxを使用することがプロトコルの意図されたユースケースであった場合、そもそも他のステータスコードはありません。


3

アプリケーションエラーの場合も、5xxエラーを忘れないでください。

この場合、409(競合)はどうですか?これは、ユーザーが格納されたリソースを削除することで問題を修正できることを前提としています。

それ以外の場合は、507(完全に標準ではない)でも機能する可能性があります。エラーに200を使用しない限り、200は使用しません。


-2

クライアントクォータを超えた場合はサーバーエラーです。この場合は5xxを避けてください。


3
サーバーエラーの場合、なぜ5xxシリーズのエラーを回避するのですか?
mikek3332002

7
「クライアントクォータ超過」はサーバーエラーではなく、クライアントの制限であり、4xx未満である必要があります。
MyGGaN 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.