web-dev-qa-db-ja.com

REST APIエラーリターンのグッドプラクティス

REST AP​​Iからエラーが返されるようになる場合は、グッドプラクティスに関するガイダンスを探しています。私は新しいAPIに取り組んでいるので、今すぐにそれを任意の方向に向けることができます。現時点では私のコンテンツタイプはXMLですが、将来的にはJSONをサポートする予定です。

たとえば、クライアントが新しいリソースを追加しようとしたが、自分のストレージクォータを超えたなど、いくつかのエラーケースを追加しています。私はすでにHTTPステータスコード(認証用に401、承認用に403、そして不正なリクエストURI用に404)を使って特定のエラーケースを処理しています。私は祝福されたHTTPエラーコードを調べましたが、400-417の範囲のどれもアプリケーション固有のエラーを報告するのに正しいとは思えません。そのため、最初は200 OKと特定のXMLペイロードを使用してアプリケーションエラーを返したくなりました(つまり、もっと支払いをすれば、必要なストレージが手に入ります)。恐怖で肩をすくめて)。そのうえ、私はエラー応答を別々のケースに分割しているように感じます、httpステータスコード主導のものとコンテンツ主導のものがあります。

それでは、業界の推奨事項は何ですか?グッドプラクティス(理由を説明してください!)また、クライアントの問題から、REST AP​​Iのエラー処理によってクライアントコードの作業が楽になりますか。

594
Remus Rusanu

そのため、最初は200 OKと特定のXMLペイロードを使用してアプリケーションエラーを返したくなりました(つまり、もっと支払いをすれば、必要なストレージが手に入ります)。恐怖で肩をすくめて)。

リクエストに問題がなければ、200を返すことはありません。 RFC2616 から、200は「要求が成功した」ことを意味します。

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

サーバーは要求を理解しましたが、それを満たすことを拒否しています。承認は助けにならないでしょうし、要求は繰り返されるべきではありません。リクエストメソッドがHEADではなく、リクエストが満たされなかった理由をサーバが公表したい場合は、エンティティ内で拒否された理由を説明する必要があります。サーバーがこの情報をクライアントが利用できるようにしたくない場合は、代わりにステータスコード404(Not Found)を使用できます。

これはクライアントに要求はOKであったが失敗したことを伝えています(200ではできないこと)。これにより、レスポンスボディで問題(およびその解決策)を説明する機会も得られます。

他にどのような具体的なエラー条件を念頭に置いていますか?

212
Rich Apodaca

あなたのAPIの正しいHTTPエラーコードを選ぶための素晴らしいリソース: http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

記事からの抜粋:

どこから始めれば:

enter image description here

2XX/3XX:

enter image description here

4XX:

enter image description here

5XX:

enter image description here

523
Omar Ali

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

どちらの方法でもうまくいきます。厳密に言えば、RESTのアイデアの1つは、APIの一部としてHTTPステータスコードを使用することです(成功した場合は200または201、それに応じて4xxまたは5xxを返す)。しかし、REST policeはありません。あなたがやりたいことができます。私は、はるかに悪名高い非REST APIが「RESTful」と呼ばれているのを見ました。

この時点で (2015年8月)私はあなたのAPIの一部としてHTTPステータスコードを使用することをお勧めします。フレームワークを使用すると、以前よりもリターンコードが見やすくなりました。特に、今までよりも200以外の返品と200以外の返答の本文が見やすくなりました。

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

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

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

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

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

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

  2. あなたの返答にはすべて「封筒」または「ヘッダー」の情報を含めるべきです。通常は次のようなものです。

    envelope_ver:1.0 
     status:#あなたが好きなコードを使う。成功のためにコードを予約してください。 
     msg: "ok"#コードを反映した人間の文字列。デバッグに便利
     data:...#もしあれば、レスポンスのデータ。
  3. レスポンスのステータスは常に同じ場所(サブコードは不要)、コードの制限はなく、HTTPレベルのステータスコードを取得する必要もないため、この方法はクライアントにとってより簡単になります。

これは似たような考えの投稿です: http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

主な問題:

  1. 必要に応じてapiの意味を後で変更できるように、必ずバージョン番号を含めてください。

  2. 資料...

86
Larry K

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

40
Julian Reschke

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

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

22
SerialSeb

私はこれが当事者にとって非常に手遅れであることを知っています、しかし今、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 )。

19
Jørn Wildt

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)

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

18
aleemb

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

HTTP 200エンベロープでエラー応答を送信することは誤解を招く可能性があり、クライアント(APIコンシューマ)にメッセージの解析を強制します。おそらく、非標準的な方法または独自の方法で行われます。これも効率的ではありません - あなたは「本当の」応答状態を理解するためにあなたのクライアントに毎回HTTPペイロードをパースすることを強いるでしょう。これは処理を増やし、待ち時間を増やし、そしてクライアントがミスをする環境を作ります。

9
Kingz

既存の「ベストプラクティス」に基づいてapiをモデル化することが有効な方法かもしれません。たとえば、Twitterがエラーコードを処理する方法は次のとおりです https://developer.Twitter.com/en/docs/basics/response-codes

6
Gokul

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

5
rahil008

アプリケーションエラーについても5xxエラーを忘れないでください。

この場合、409(Conflict)はどうですか?これは、ユーザーが保存されているリソースを削除することで問題を解決できることを前提としています。

そうでなければ507(完全に標準的ではない)も動作するかもしれません。一般的なエラーに200を使わない限り、私は200を使いません。

3
Kathy Van Stone