web-dev-qa-db-ja.com

REST APIは、500の内部サーバーエラーを返して、クエリが存在しないオブジェクトを参照していることを示す必要がありますか?

私はREST APIを使用しています。このAPIは、多数のIoTデバイスのデータを処理するサーバーに常駐しています。

私の仕事は、APIを使用してサーバーにクエリを送信し、上記のデバイスに関する特定のパフォーマンス情報を収集することです。

ある例では、利用可能なデバイスとそれに対応する識別子のリストを取得し、後でそれらの識別子(GUID)を使用してサーバーに詳細を問い合わせます。

サーバーは、これらのIDの1つに対するクエリに対して500 Internal Server Errorを返しています。私のアプリケーションでは、例外がスローされ、エラーの詳細が表示されません。 Postman を使用して応答をさらに詳しく調べると、サーバーが以下を含む本文でJSONを返したことがわかります。

errorMessage: "This ID does not exist"

サーバーが最初にIDを提供したという事実は無視してください-これは開発者にとって別の問題です

REST APIが500 Internal Server Errorを返して、クエリが存在しないオブジェクトを参照していることを報告する必要がありますか?私の考えでは、HTTP応答コードは厳密にREST呼び出しであり、APIの内部メカニズムではありません。エラーと説明を含む200 OKの応答が必要です。これは、問題のAPIに固有のものです。


REST呼び出しがどのように構成されているかによって、期待値に潜在的な違いがあることに気づきました。

次の例を検討してください。

  1. http://example.com/restapi/deviceinfo?id=123
  2. http://example.com/restapi/device/123/info

最初のケースでは、デバイスIDはGET変数として渡されます。 404または500は、パス(/restapi/deviceinfo)が見つからないか、サーバーエラーが発生したことを示します。

2番目のケースでは、デバイスIDはURLの一部です。私は404 Not Foundについて理解を深めることができますが、パスのどの部分がエンドポイントではなく変数として解釈されるかに基づいて議論することもできます。

40
JYelton

ここで404応答が最も意味論的に一致すると思います。これは、検索しようとしているリソース(クエリに使用されたURIで表される)が見つからなかったためです。本文でエラーペイロードを返すことは妥当ですが、必須ではありません。

RFC 2616 によると、404ステータスコードの定義は次のとおりです。

10.4.5 404が見つかりません
サーバーはリクエストURIに一致するものを見つけられませんでした。状態が一時的であるか永続的であるかは示されません。 410(Gone)ステータスコードは、内部的に構成可能なメカニズムによって、古いリソースが永続的に利用できず、転送アドレスがないことをサーバーが認識している場合に使用する必要があります(SHOULD)。このステータスコードは、サーバーが要求が拒否された理由を正確に明らかにしたくない場合、または他の応答が該当しない場合に一般的に使用されます。

96
Andy Hunt

私はあなたの例を使用します。

http://example.com/restapi/deviceinfo?id=12

エンドポイントがjsonarrayを返す場合、最適な選択肢は200 OK結果が見つからなかった場合は空の配列。

エンドポイントが単一の結果を返すように設計されている場合、私の選択は404 NOT FOUND、私にとって、この種のエンドポイントの正しい構文は次のとおりです:http://example.com/restapi/deviceinfo/123。通常、リクエストパラメータはフィルタリングとエンドポイントが配列を返すときにのみ使用します。

http://example.com/restapi/device/123/info

この質問はすでに回答されていると思います here 。 POSTまたはGET、より良い選択のようです404 NOT FOUNDリソースのため123 見つかりませんでした。

どちらの場合も、リクエストが完了しなかった理由を説明する必要性がわかりません。リクエスト情報とHTTPコードは、その理由をすでに説明しています。

34
Dherik

HTTP 404は正解です。サーバーはクライアントが要求しているリソースを理解していますが、そのリソースは持っていません。

「REST API」を使用していることが重要です。 APIは、関数を実行するのではなく、REpresentational State Transferを実行するように動作する必要があります。 (確かに、「REST」という用語はより広い意味を持つようになりましたが、ここでもその文字通りの意味を使用して効果を上げることができます。)クライアントは、URLで記述されたリソースの状態を要求しましたhttp://example.com/restapi/device/123/info。クエリ文字列(/deviceinfo?id=123)は状況を変えません。サーバーは、デバイス123の状態を転送するよう要求していることを認識していますが、それを既知のリソースとして認識していません。したがって、HTTP 404

ここで説明する他の可能な応答には、特定の意味もあります。

  • HTTP 200-状態を取得しました。レスポンスボディにあります。
  • HTTP 204-状態を取得しました。空白です。
  • HTTP 400-どのリソースについてお伺いしているのかわかりません。 URLを修正してください。
  • HTTP 500-不具合がありました。あなたのせいではありません。

RFC 2616 Secを参照してください。必要に応じて10。

27
Travis Wilson

5xxエラーは通常、サーバーでエラーが発生し、リクエストを完了できないことを示すために使用されます。サーバーが要求を受け取り、それを正常に解析でき、その後、その作業を実行する場合、5xxエラーは返されません。

クエリが結果を返さない場合に何を返すかについて何らかの規則があるかどうかはわかりません。私はあなたが説明したもの(メッセージを含むボディを持つ200)と、結果が見つからなかったことを示す404の両方を見てきました。 200はおそらく最も理にかなっています-要求は正常に完了し、クライアントの要求やサーバーが要求を処理している間に問題はありませんでした。ボディはクライアントにメッセージを配信できます。


私はあなたの両方の例(http://example.com/restapi/deviceinfo?id=123http://example.com/restapi/device/123/info)を同じように扱います-123はパラメータです。どちらの場合も、ID 123のデバイスのデバイス情報を取得するリクエストを構造化する方法は異なります。

まず、承認と認証について考えます。ユーザーに適切な権限がない場合、必要に応じて403または401を返します。それは「無許可」と呼ばれていますが、私の理解では、401は認証に関するものであり、403は無許可または許可の拒否に関するものです。ただし、すべての認証と承認のエラーを403に固執したいのであれば、ここではあまりうるさくありません。

次に、IDを処理します。あなたの例に基づいて、それは数値IDのように見えます。数値以外の値が指定された場合、400を返します。パラメータが有効なデバイス識別子である可能性がある場合は、処理を続行します。他の引数がある場合は、ここでもチェックされます。レスポンスの本文には、リクエストが不正であった理由に関する適切な情報が含まれていると思います。

すべてのパラメーターが有効であれば、リクエストの処理を開始します。システムまたは依存関係(データベース、サードパーティサービス、別の内部サービス)が利用できない場合、5xxコードを返します-503は特定のものですが、500も許容されます。どちらの場合も、追加の詳細を含む本文を返します。外部依存関係が408リクエストタイムアウトを報告した場合、それを食べて500をクライアントに返し、システムへのリクエストがタイムアウトした場合にのみクライアントが408を受信できるようにすることを検討してください。システムがリクエストを完了できる場合、200と適切な本文を返します。

204は便利な場合もありますが、応答本文を送信できなくなります。特にAPI設定では、ログまたはレポートのメカニズムに入力できる情報を含む応答本文を送信することは、ほとんどの場合正しい判断のように思えます。

404が返されるのは、サーバーに/deviceinfoエンドポイントまたは/device/:id/infoエンドポイントがない場合のみです。

見つからないIDは、見つからないリソースと同じであるとは見なしません。リソースは、(例では)特定のデバイスのデバイス情報です。 404を返すことは、リソース(デバイス情報)が存在しないことを意味します。適切なボディを持つ200は、システムが実際にデバイス情報を提供できることを意味します。指定されたIDを持つデバイスがある場合とない場合があります。

11
Thomas Owens

500シリーズのHTTPエラーは、サーバーの誤動作を示します。の他に 501 Not Implementedおよび505 HTTP Version Not Supported、これらのエラーコードを使用すると、後でリクエストを再試行しても成功する可能性があります(ただし、503 Service Unavailableはこれを明示的に示しています)。理想的には、サーバーはこれらのコードの1つを生成するべきではありませんが、バグのないソフトウェアを記述してサーバーに無限のリソースをプロビジョニングできないことは、それらを時々必要とすることを意味します。

「オブジェクトが存在しない」という結果の場合、おそらく404 Not Found(名前でオブジェクトを要求する場合)、または200 Success空の結果本文(属性でオブジェクトを検索する場合)。 204 No Contentは魅​​力的なように見えますが、レスポンスボディの欠如が予期される結果である状況でのみ使用します。

5
Mark

APIのクライアントとして、私が次のいずれかの呼び出しを行うと、

  1. http://example.com/restapi/deviceinfo?id=123
  2. http://example.com/restapi/device/123/info

私はDeviceInfoオブジェクト(またはその表現)が返されることを期待しています(または、いずれにせよ、それが正式なタイプでも、ドキュメント化された「ダックタイプ」の規則に準拠したものでも)。が欲しい 200ステータスは、実際に取得したことを意味し、先に進んで使用できます。

REST APIの場合、400と500のステータスコードは例外のようなものだと思います。受け取ったリクエストに対して「通常の」応答を返すことができないときを示すために使用します。そのため、クライアントは、取得することを期待していた情報を処理するのではなく、例外的なことを行う必要があります。

これは、APIコンシューマーとして、応答を取得したり、例外をスローしたりする、ある種のchecked-rest-call関数を使用できることを意味します。それは素晴らしいことです;通常のロジックは直線コードにすることができ、ローカルコードで行うのと同じ方法でエラー処理を整理できます。予期しない404は、何もしなくても "リソースが見つかりません"例外として現れます。後で処理するときに "属性がありません"エラーとしてではありません{ errorMessage: "Device 123 not found" }DeviceInfoオブジェクトであるかのように。

エンドポイントhttp://example.com/restapi/deviceinfoisが見つかり、id=123そうではないため、本文にエラーメッセージを含む200を返し、正しい結果またはエラーコードのいずれかを返す可能性のあるC関数と同じ種類のインターフェイスの問題、またはnullを任意に返すことによる問題。通常の返品からの「個別の」チャネルを通じてエラーが示されることは、インターフェースのユーザーとしてはるかに優れています。これは、HTTP 200、404、および500応答が低レベルの観点から同じチャネルであっても、ここでも当てはまります。これらは標準化されており、簡単に区別できるため、私のRESTクライアントフレームワークは、これらのステータスを簡単に切り替えて、言語の適切な構造に変えることができます。JSONレイヤーで同じことを行う(常に200と言って、DeviceInfoまたはエラーメッセージのいずれかを表示します)使用するJSONスキーマの知識を埋め込む必要があります。

したがって、期待されるタイプの有効な値を返すことができる場合にのみ200を使用してください(そのため、http://example.com/restapi/search-devices?colour=blue青いデバイスがない場合、空の配列で200を返すことができます。空の配列は有効な配列であり、「すべての青いデバイスの詳細が欲しい」という要求に対する賢明な回答です。できない場合は、最も適切な200以外のステータスコードを使用してください。 「デバイス123が存在しません」は「デバイス123の詳細を教えてください」に対する正しい応答であり、サーバーのエラーではありませんが、クライアントが期待する例外です「DeviceInfo」が返され、通常の「ここに要求されたものです」という応答は送信されません。

1
Ben

エラー422 Unprocessable Entityを使用して、404 not foundと区別できます。 422は、サーバーは要求を理解しますが、適切な応答を提供できないことを意味します。同様の状況でこのコードを使用しています。

0
FiNeX

エラー500は通常、要求がサーバー側プログラムをクラッシュさせたことを示します。エンタープライズ環境では、これらのエラーは一見して卵として扱われ、回避されています。

エラー4xxは、APIエンドポイント(リソース)が存在しないことをプログラマーに知らせます。したがって、適切なエンドポイントに到達すると、それ以降のエラー処理はAPIのプログラマーの責任であり、適切に処理する必要があります。つまり、200応答のエラーメッセージが表示されます。

0
postronnim

W3は、404は 他に該当する応答がない場合 の場合に使用されると説明していますが、これは204(コンテンツなし)応答が適していると思いませんか?リクエストは処理の観点からは有効であり、サーバーはリクエストを処理して結果を返します。それは成功であり、2xx応答に傾いています。この特定のリクエストにはコンテンツがなかったため、204はユーザーに、クエリに問題はないが何もないことを通知します。

また、409(競合)が適切な応答であるという弱い主張をすることもできます。 409はPOSTに最もよく使用されますが、

リソースの現在の状態と競合しているため、要求を完了できませんでした。このコードは、ユーザーが競合を解決してリクエストを再送信できると予想される状況でのみ許可されます。レスポンスボディには、ユーザーが競合の原因を認識するのに十分な情報を含める必要があります(SHOULD)。理想的には、応答エンティティには、ユーザーまたはユーザーエージェントが問題を修正するのに十分な情報が含まれます。ただし、それは不可能である場合があり、必須ではありません。

要求されたIDが存在しないことは間違いなくここでの競合であり、そのようなIDがシステムに存在しないことをメッセージで返すことは、ユーザーが競合を認識して修正するのに十分な情報です。

0
moneyt

他の答えはそれをカバーします、しかし私はちょうど500シリーズのエラーが「私が台無しにした」ことを意味することを指摘したかっただけです。この場合、「I」はAPIを意味するため、未処理のサーバーエラーなどです。 400シリーズのエラーは、「ごちゃごちゃした」ことを意味します。APIの呼び出し側が誤ったものを送信しました。

0
Marcie