たとえば、のGETリクエストを実行しましusers/9
たが、ID#9のユーザーがいません。最良の応答コードはどれですか?
- 200 OK
- 202承認済み
- 204コンテンツなし
- 400不正な要求
- 404お探しのページが見つかりませんでした
たとえば、のGETリクエストを実行しましusers/9
たが、ID#9のユーザーがいません。最良の応答コードはどれですか?
私は404に強く反対し、データが空の204または200を支持します。または、少なくとも1つは404で応答エンティティを使用する必要があります。
リクエストは受信され、適切に処理されました。サーバー上でアプリケーションコードがトリガーされたため、クライアントエラーであるとは言えず、クライアントエラーコードのクラス全体(4xx)が適合していません。
さらに重要なことに、404はいくつかの技術的な理由で発生する可能性があります。たとえば、サーバー上でアプリケーションが一時的に非アクティブ化またはアンインストールされている、プロキシ接続の問題などです。
確かに、そのような場合には5xxエラークラスが存在しますが、実際には、影響を受けるミドルウェアコンポーネントは、エラーが自分の側にあることを認識できず、エラーがクライアント側にあると想定して、404で応答することがよくあります。 500/503の代わりに。
したがって、ステータスコードだけに基づいて、クライアントは「空の結果セット」を意味する404と「何かが深刻に間違っている。このエラーを運用チームに報告する」を意味する404を区別できません。
これは致命的となる可能性があります。年次ボーナスが必要なすべての従業員を一覧表示する、会社の会計サービスを想像してみてください。残念ながら、一度呼び出されると404が返されます。これは、誰もボーナスを受け取る必要がないことを意味しますか、それともアプリケーションが現在新しいデプロイメントのためにダウンしていることを意味しますか?
->一時的にアクセスできないだけでなく、要求されたリソースが確実に存在しないことを知る必要があるアプリケーションの場合、応答エンティティのない404はほとんど使用できません。
また、多くのクライアントフレームワークは、それ以上の質問をせずに例外をスローすることで404に応答します。これにより、クライアント開発者はその例外をキャッチして評価し、それに基づいて、監視コンポーネントなどによって検出されたエラーとしてログに記録するか、無視するかを決定する必要があります。それは私にもきれいに思えません。
204に対する404の利点は、要求されたリソースが見つからなかった理由に関する情報を含む可能性のある応答エンティティを返すことができることです。しかし、それが本当に適切である場合は、200 OK応答の使用を検討し、ペイロードデータでエラー応答を許可するようにシステムを設計することもできます。または、404応答のペイロードを使用して、構造化された情報を呼び出し元に返すこともできます。たとえば、解析可能なXMLまたはJSONの代わりにhtmlページを受け取った場合、それは、呼び出し元の観点から有効である可能性のある「結果なし」の応答ではなく、技術的な問題が発生したことを示す良い指標です。または、そのためにHTTP応答ヘッダーを使用することもできます。
それでも私は空の応答で204または200を好むでしょう。このようにして、リクエストの技術的な実行のステータスがリクエストの論理的な結果から分離されます。2xxは、「技術的な実行はOKです。これは結果です。対処してください」という意味です。
ほとんどの場合、空の結果が受け入れられるかどうかを判断するのはクライアントに任せるべきだと思います。正しい技術的実行にもかかわらず、応答エンティティなしで404を返すことにより、クライアントは、ケースを単にエラーではないエラーと見なすことができます。
もう1つの簡単な例え:「結果が見つかりません」に対して404を返すことは、SQLクエリが結果を返さなかった場合にDatabaseConnectionExceptionをスローすることに似ています。それは仕事を成し遂げることができますが、同じ例外をスローする可能性のある技術的な原因がたくさんあり、それは有効な結果と間違えられます。
別の観点:運用の観点から、404は問題がある可能性があります。有効なサービス応答ではなく接続の問題を示している可能性があるため、調査および修正が必要な真の技術的問題を隠す可能性のある、メトリック/ダッシュボード内の「有効な」404の変動数は必要ありません。
編集:うわー、これは多くの論争を引き起こしました。404に対する別の議論は次のとおりです。厳密にHTTP仕様(RFC7231)の観点から、404はリソースが存在しないことを意味することすらありません。これは、サーバーに要求されたリソースの現在の表現がないことを意味するだけであり、これは一時的なものである可能性もあります。したがって、厳密にHTTP仕様では、404は、要求されたものが存在しないことに関して本質的に信頼できません。要求されたものが積極的に存在しないことを伝えたい場合は、404を使用しないでください。
TL; DR:使用404
このブログを参照してください。それはそれを非常によく説明しています。
ブログのコメントの要約204
:
204 No Content
ブラウザの応答コードとしてはそれほど有用ではありません(ただし、HTTP仕様によれば、ブラウザは「ビューを変更しない」応答コードとして理解する必要があります)。204 No Content
ただし、何かを返すことなく成功を示したい場合があるajaxWebサービスには非常に便利です。(特に、フィードバックを必要としないDELETE
またはのような場合)。POST
したがって、あなたの質問に対する答えは404
、あなたの場合の使用です。204
は特殊な応答コードであり、に応答してブラウザに戻ることはあまりありませんGET
。
204
およびよりもさらに適切でない他の応答コード404
:
200
正常にフェッチしたものの本文とともに返される必要があります。フェッチしているエンティティが存在しない場合は適切ではありません。202
サーバーがオブジェクトの処理を開始したが、オブジェクトの準備がまだ完全に整っていない場合に使用されます。確かにここではそうではありません。GET
リクエストに応じてユーザー9の構築を開始しておらず、開始することもありません。それはあらゆる種類の規則を破ります。400
不適切にフォーマットされたHTTPリクエスト(たとえば、不正な形式のhttpヘッダー、誤った順序のセグメントなど)に応答して使用されます。これは、使用しているフレームワークによってほぼ確実に処理されます。独自のサーバーを最初から作成しているのでない限り、これに対処する必要はありません。編集:新しいRFCでは、意味的に無効な要求に400を使用できるようになりました。ウィキペディアのHTTPステータスコードの説明は特に役立ちます。www.w3.orgのHTTP/1.1RFC2616ドキュメントでも定義を確認できます。
最初は204が理にかなっていると思いましたが、話し合いの結果、404が唯一の真の正解だと思います。次のデータを検討してください。
ユーザー:ジョン、ピーター
METHOD URL STATUS RESPONSE
GET /users 200 [John, Peter]
GET /users/john 200 John
GET /unknown-url-egaer 404 Not Found
GET /users/kyle 404 User Not found
GET /users?name=kyle` 200 []
DELETE /users/john 204 No Content
いくつかの背景:
検索で配列が返されます。一致するものはありませんでしたが、内容は空の配列です。
もちろん、404は、要求されたサーバーでサポートされていないURLで最もよく知られていますが、不足しているリソースは実際には同じです。と一致して
いても、ユーザーKyleは利用可能なリソースではないため、404が引き続き適用されます。これは検索クエリではなく、動的URLによる直接参照であるため、404です。/users/:name
users/kyle
コメントで提案した後、404のメッセージをカスタマイズすることは、APIコンシューマーが、完全な不明なルートと欠落しているエンティティをさらに明確に区別するのに役立つもう1つの方法です。
とにかく、私の2セント:)
リソースが存在することが予想されるが、それが空である可能性がある場合は、物が空であることを示す表現で200OKを取得する方が簡単かもしれないと主張します。
したがって、/thingsが{"Items":[]}で200 OKを返すようにしたいと思います。これは、アイテムが0のコレクションは、アイテムが1つあるコレクションとまったく同じように扱うことができるためです。その中のより多くのアイテム。
PUTとDELETEの204NoContentはそのままにしておきますが、実際には有用な表現がない場合があります。
/ things / 9が実際に存在しない場合は、404が適切です。
以前のプロジェクトでは、404を使用しました。ユーザー9がいない場合、オブジェクトは見つかりませんでした。したがって、404NotFoundが適切です。
オブジェクトは存在するがデータがない場合、204コンテンツなしが適切です。あなたの場合、オブジェクトは存在しないと思います。
2つの質問があります。タイトルに1つ、例に1つ。これは、どの対応が適切かについての論争の量に部分的につながったと思います。
質問のタイトルは、空のデータについて尋ねます。空のデータはまだデータですが、データがないことと同じではありません。したがって、これは、おそらくからの結果セット、つまりリストを要求することを示唆してい/users
ます。リストが空の場合でもリストであるため、204(コンテンツなし)が最適です。ユーザーのリストを要求し、リストが提供されましたが、たまたまコンテンツがありません。
代わりに、提供されている例では、特定のオブジェクト、ユーザー、について質問しています/users/9
。ユーザー#9が見つからない場合、ユーザーオブジェクトは返されません。特定のリソース(ユーザーオブジェクト)を要求しましたが、見つからなかったために与えられなかったため、404が適切です。
これを解決する方法は、条件ステートメントを追加せずに期待どおりに応答を使用できる場合、204を使用するか、404を使用することだと思います。
私の例では、コンテンツが含まれているかどうかを確認せずに空のリストを反復処理できますが、何かを壊したり、nullかどうかを確認するためのチェックを追加したりせずに、nullオブジェクトにユーザーオブジェクトデータを表示することはできません。
もちろん、必要に応じてnullオブジェクトパターンを使用してオブジェクトを返すこともできますが、それは別のスレッドの議論です。
要約または単純化するために、
2xx:オプションのデータ:整形式のURI:基準はURIの一部ではありません:@RequestBodyで指定できる基準がオプションの場合、@RequestParamは2xxになります。例:名前/ステータスでフィルタリング
4xx:期待されるデータ:整形式ではないURI:基準はURIの一部です:@PathVariableでのみ指定できる基準が必須である場合、4xxになります。例:一意のIDによるルックアップ。
したがって、尋ねられた状況では、「users / 9」は4xx(おそらく404)になりますが、「users?name = superman」の場合は2xx(おそらく204)になります。
w3の投稿によると、
200 OK
リクエストは成功しました。応答とともに返される情報は、要求で使用されたメソッドによって異なります。
202承認済み
リクエストは処理のために受け入れられましたが、処理は完了していません。
204コンテンツなし
サーバーは要求を実行しましたが、エンティティ本体を返す必要はなく、更新されたメタ情報を返したい場合があります。
400不正な要求
構文が正しくないため、サーバーは要求を理解できませんでした。クライアントは変更せずにリクエストを繰り返すべきではありません
401無許可
リクエストにはユーザー認証が必要です。応答には、WWW-Authenticateヘッダーフィールドを含める必要があります
404お探しのページが見つかりませんでした
サーバーは、Request-URIに一致するものを検出しませんでした。状態が一時的であるか永続的であるかは示されません
既存の回答で詳しく説明されていないのは、パスパラメータを使用するかクエリパラメータを使用するかに違いがあるということです。
/users/9
に応答する必要があります。はリソースであり、結果は単項、またはエラーであり、存在しません。これはモナドではありません。404
/users/9
/users?id=9
に応答する必要があります。リソースが存在し、結果はn-aryであり、空であっても存在します。が一意の場合、これはモナドです。204
/users
/users
id
パスパラメータを使用するかクエリパラメータを使用するかは、ユースケースによって異なります。私は、必須、規範的、または識別引数のパスパラメーターと、オプション、非規範的、または帰属引数(ページング、照合ロケールなど)のクエリパラメーターを好みます。REST APIでは、最初の公開sshキーを取得したり、3番目の住所を取得したりするなど、「子レコード」を取得するためのネストが可能であるため、特に使用し/users/9
ません。/users?id=9
/users/9/ssh-keys/0
/users/9/address/2
私は404を使用することを好みます。理由は次のとおりです。
204
メソッドのようなvoid
ものです。、、、およびGET
にのみ使用します。識別子がパスパラメータではなくクエリパラメータである場合は例外とします。POST
PUT
DELETE
GET
NoSuchElementException
、またはそのようなものであるため、クライアントエラーです。ArrayIndexOutOfBoundsException
204
とは、回避できるコード内の追加の分岐を意味します。クライアントコードが複雑になり、場合によってはサーバーコードも複雑になります(エンティティ/モデルモナドを使用するか、プレーンエンティティ/モデルを使用するかによって異なります。エンティティ/モデルモナドから離れることを強くお勧めします。モナドのうち、操作が成功したと思い、実際に何か他のものを返す必要があるときに200または204を返します)。最後になりましたが、一貫性
GET /users/9
PUT /users/9
とDELETE /users/9
PUT /users/9
更新または削除が成功した場合は、DELETE /users/9
すでに戻る必要があります。204
では、ユーザー9が存在しなかった場合、彼らは何を返す必要がありますか?使用するHTTPメソッドに応じて、同じ状況が異なるステータスコードとして表示されることは意味がありません。
その上、規範的ではなく、文化的な理由:プロジェクトで発生する次のことに204
使用される場合、誰かがn-aryメソッドに戻るのは良いと考えるということです。そして、それはクライアントコードを複雑にします。なぜなら、本体をチェックしてからデコードするのではなく、クライアントは本体を具体的にチェックしてからデコードする必要があり、その場合は本体のデコードをスキップする必要があるからです。代わりにクライアントは何をしますか?空の配列を作成しますか?では、それをネットワークに接続してみませんか?クライアントが空の配列を作成する場合、204は愚かな圧縮の一形態です。クライアントが代わりに使用する場合、まったく異なるワームの缶が開かれます。GET /users/9
204
2xx
204
null
問題を調べた後、404
なぜ使用すべきではありませんか?
RFC 7231に基づくと、正しいステータスコードは次のとおりです。204
上記の回答で、私は1つの小さな誤解に気づきました。
1.-リソースは次のとおりです。/users
2.-/users/8
はリソースではありません。これは次のとおりです。/users
ルートパラメータを持つリソース8
、消費者はそれに気付かず、違いを知らないかもしれませんが、発行者はこれを知っている必要があります!...したがって、消費者に正確な応答を返す必要があります。限目。
それで:
RFCに基づくと、リソース/users
が見つかったため404は正しくありませんが、パラメーターを使用して実行されたロジックでは、応答として返される8
ものが見つからなかったcontent
ため、正解は次のとおりです。204
ここでの主なポイントは404
、内部ロジックを処理するリソースさえ見つからなかったということです。
204
は:リソースを見つけました。ロジックは実行されましたが、routeパラメーターで指定された基準を使用したデータが見つからなかったため、何も返すことができません。申し訳ありませんが、基準を確認して、もう一度お電話ください。
200
:わかりました。リソースが見つかりました。ロジックが実行されました(Imが何も返さない場合でも)これを取得して、自由に使用してください。
205
:( GET応答の最良のオプション)リソースを見つけました。ロジックが実行されました。コンテンツがいくつかあります。よく使用してください。ちなみに、これをビューで共有する場合は、ビューを更新してください。表示します。
それが役に立てば幸い。
このスレッドで、非常に単純で明確に定義されたものが「意見ベース」になったのは悲しいことです。
HTTPサーバーは、静的Webページ、検索結果のリスト、他のエンティティのリスト、何かのjson記述、メディアファイルなど、あらゆるコンテンツの抽象化である「エンティティ」のみを認識します。
このような各エンティティは、一意のURLで識別できることが期待されます。
サーバーが指定されたURLでリソースを見つけた場合、その内容が何であるかは関係ありません-2Gのデータ、null、{}、[]-存在する限り、200になります。ただし、そのようなエンティティがサーバーに認識されていないため、404「NotFound」を返すことが期待されます。
1つの混乱は、アプリケーションに特定のパス形状のハンドラーがある場合、それはエラーではないはずだと考える開発者からのようです。HTTPプロトコルの観点からは、サーバー上に一致するエンティティがない限り、サーバーの内部で何が起こったか(つまり、デフォルトルーターが応答したか特定のパス形状のハンドラーか)は関係ありません。有効なコンテンツ(空またはその他)を返す要求されたURL(MP3ファイル、Webページ、ユーザーオブジェクトなどを要求したもの)。404(または410など)である必要があります。
もう1つの混乱点は、「データなし」と「エンティティなし」にあるようです。前者は実体の内容に関するものであり、後者はその存在に関するものです。
例1:
例2:
例3:
Twitterは404を使用し、「データが見つかりません」などのカスタムエラーメッセージを表示します。
参照:https ://developer.twitter.com/en/docs/basics/response-codes.html
どちらも本当に適切ではないと思います。すでに述べたように、たとえば@annebによっても、問題の一部はHTTP応答コードを使用してRESTfulサービスに関連するステータスを転送することから生じると思います。RESTサービスが自身の処理について言わなければならないことはすべて、REST固有のコードを使用して転送する必要があります。
HTTPサーバーが、送信されたリクエストに応答する準備ができているサービスを見つけた場合、HTTP 404で応答するべきではないと私は主張します。最終的には、サーバーによって何かが見つかりました。リクエストを処理するサービス。
少しの間、次のURLを想定しましょうhttp://example.com/service/return/test
。
404
正しいです。ある種のサービスにこのファイルを正確に配信するように要求し、そのサービスがその名前の何も存在しないことを通知する場合も、同じことが言えます。明示的に異なる動作を必要とするサービスからの応答がない場合、HTTPサーバーは次の3つのことしか言うことができません。
503
要求を処理することになっているサービスが実行されていないか、応答していない場合。200
それ以外の場合、HTTPサーバーは実際に要求を満たすことができるため、サービスが後で何を言おうとも関係ありません。400
または404
、そのようなサービスがなく(「存在するがオフライン」ではない)、他に何も見つからなかったことを示すため。手元の質問に戻ると、最もクリーンなアプローチは、前述以外の応答コードをHTTPで使用しないことだと思います。サービスが存在し、応答している場合、HTTPコードは200である必要があります。応答には、サービスが別のヘッダーで返したステータスが含まれている必要があります。ここで、サービスは次のように言うことができます。
REST:EMPTY
たとえば、sthを検索するように求められた場合。そしてその研究は空に戻った。REST:NOT FOUND
特にsthを求められた場合。「IDのような」– IDまたはエントリ番号24などのファイル名またはリソースであり、特定のリソースが見つかりませんでした(通常、1つの特定のリソースが要求され、見つかりませんでした)。REST:INVALID
送信されたリクエストの一部がサービスによって認識されない場合。(これらの前に「REST:」を付けたのは、HTTP応答コードと同じ値または表現である可能性があるが、完全に異なるという事実を示すためであることに注意してください)
上記のURLに戻って、ケースBを調べてみましょう。ここで、サービスはHTTPサーバーに対して、このリクエスト自体を処理せず、に渡すことを示していますSERVICE
。HTTPは、によって返されるものだけを提供します。HTTPは、によって渡される部分SERVICE
については何も知りません。そのサービスが実行されている場合、HTTPは、要求を処理するための何かを実際に見つけたので、戻る必要があります。return/test
SERVICE
200
によって返されるステータスSERVICE
(および上記のように、別のヘッダーに表示したいステータス)は、実際に期待されるアクションによって異なります。
return/test
特定のリソースを要求する場合:存在する場合は、ステータスが;のリソースを返しますREST:FOUND
。そのリソースが存在しない場合は、REST:NOT FOUND
;を返します。REST:GONE
これは、かつて存在していて戻らないことREST:MOVED
がわかっていて、ハリウッドになっていることがわかっている場合は、戻るように拡張できます。return/test
の空のセットを返します。REST:EMPTY
要求されたタイプとステータスの結果のセットREST:SUCCESS
return/test
が認識された操作ではない場合:完全に間違っている場合(たとえば、のようなタイプミス)、または後で計画されている場合はSERVICE
戻ります。REST:ERROR
retrun/test
REST:NOT IMPLEMENTED
この区別は、2つの異なるものを混ぜ合わせるよりもはるかに明確です。また、デバッグが容易になり、処理が少しでも複雑になります。
問題と議論は、HTTP応答コードが、結果がHTTPによって提供されるサービスの状態を示すため、またはsthを示すために使用されているという事実から生じます。これは、HTTPサーバー自体のスコープには含まれていません。この不一致のため、質問に答えることができず、すべての意見が多くの議論の対象となります。
HTTPサーバーではなくサービスによって処理される要求の状態は、HTTP応答コードによって指定されるべきではありません(RFC 6919)。HTTPコードSHOULD(RFC 2119)には、HTTPサーバーが独自のスコープから提供できる情報(つまり、サービスが要求を処理することがわかったかどうか)のみが含まれている必要があります。
代わりに、実際にリクエストを処理しているサービスへのリクエストの状態についてコンシューマーに通知するために、別の方法を使用する必要があります。私の提案は、特定のヘッダーを介してそうすることです。理想的には、ヘッダーの名前とその内容の両方が、消費者がこれらの応答を簡単に操作できるようにする標準に準拠しています。
RFC7231-page59(https://www.rfc-editor.org/rfc/rfc7231#page-59)によると、404ステータスコード応答の定義は次のとおりです。
6.5.4。404 Not Found 404(Not Found)ステータスコードは、オリジンサーバーがターゲットリソースの現在の表現を見つけられなかったか、存在することを開示する意思がないことを示します。404ステータスコードは、この表現の欠如が一時的であるか永続的であるかを示しません。オリジンサーバーが、おそらく何らかの構成可能な手段を通じて、状態が永続的である可能性が高いことを知っている場合、410(Gone)ステータスコードは404よりも優先されます。404応答はデフォルトでキャッシュ可能です。つまり、メソッド定義または明示的なキャッシュ制御で特に示されていない限り([RFC7234]のセクション4.2.2を参照)。
そして、疑問をもたらす主なものは、上記のコンテキストでのリソースの定義です。同じRFC(7231)によると、リソースの定義は次のとおりです。
リソース:HTTPリクエストのターゲットは「リソース」と呼ばれます。HTTPはリソースの性質を制限しません。リソースとの対話に使用される可能性のあるインターフェイスを定義するだけです。[RFC7230]のセクション2.7で説明されているように、各リソースはURI(Uniform Resource Identifier)によって識別されます。クライアントがHTTP/1.1要求メッセージを作成するとき、クライアントは([RFC7230]のセクション5.3)で定義されているように、さまざまな形式の1つでターゲットURIを送信します。リクエストを受信すると、サーバーはターゲットリソースの有効なリクエストURIを再構築します([RFC7230]のセクション5.5)。HTTPの設計目標の1つは、リソースIDを要求セマンティクスから分離することです。これは、要求セマンティクスを要求メソッド(セクション4)といくつかの要求変更ヘッダーフィールド(セクション5)に付与することで可能になります。
したがって、私の理解では、結果が空のGETリクエストが成功した場合、404ステータスコードを使用しないでください(例:特定のフィルターの結果がないリスト)
Microsoftによると:ASP.NET Core Web APIのコントローラーアクションの戻り値の種類をほぼ下にスクロールすると、データベースに見つからないオブジェクトに関連する404に関する次の宣伝文句が見つかります。ここで彼らは、404が空のデータに適していることを示唆しています。
そのようなことは主観的である可能性があり、両側にいくつかの興味深いさまざまな確固たる議論があります。ただし、[私の意見では]欠落データに対して404を返すことは正しくありません。これを明確にするための簡単な説明は次のとおりです。
何も壊れておらず、エンドポイントが見つかり、テーブルと列が見つかったため、DBがクエリを実行し、データが「正常に」返されました。
さて、その「成功した応答」にデータがあるかどうかは関係ありません。あなたは「潜在的な」データの応答を要求し、「潜在的な」データによる応答が実行されました。ヌル、空などは有効なデータです。
200は、私たちが行ったリクエストが成功したことを意味します。データをリクエストしていますが、HTTP / RESTに問題はなく、データ(空ではありますが)が返されたため、「データのリクエスト」は成功しました。
200を返し、特定のシナリオごとに必要な空のデータをリクエスターに処理させます。
この例を考えてみましょう。
このデータが空であることは完全に有効です。これは、ユーザーに違反がないことを意味します。これはすべて有効なので200です。そうすれば、次のことができます。
違反はありません、ブルーベリーマフィンを持っています!
これを404とみなす場合、何を述べていますか?ユーザーの違反が見つかりませんでしたか?さて、文法的には正しいですが、RESTの世界では、成功または失敗がリクエストに関するものである場合、それは正しくありません。このユーザーの「違反」データは正常に検出されました。違反はありません。有効な状態を表す実数です。
[生意気なメモ..]
あなたのタイトルでは、200が正しい応答であることに無意識のうちに同意しています。
有効なリクエストで空のデータに対する適切なREST応答コードは何ですか?
主観性やトリッキーな選択に関係なく、使用するステータスコードを選択する際に考慮すべき点がいくつかあります。
多くの人が述べているように、404は誤解を招く可能性があり、要求URIが存在しないかどうか、または要求されたURIが要求されたリソースをフェッチできないかどうかをクライアントが区別することはできません。
200ステータスにはリソースデータが含まれていると予想されるため、正しい選択ではありません。204ステータスは、まったく別のものを意味するため、GETリクエストの応答として使用しないでください。
他のすべての既存のステータスは、何らかの理由で適用されません。
私はこのトピックが複数の場所で何度も議論されているのを見てきました。私にとって、トピックに関する混乱を排除するために、専用の成功ステータスが必要であることは痛々しいほど明白です。「 209-表示するリソースがありません」のようなもの。
IDが見つからないことはクライアントエラーと見なされるべきではないため、2xxステータスになります(クライアントがサーバーのDBにあるすべてを知っている場合、サーバーに何も尋ねる必要はありませんね)。この専用ステータスは、他のステータスの使用に関して議論されたすべての問題に対処します。
唯一の質問は、RFCにこれを標準として受け入れるにはどうすればよいですか?
この状況で何度も苦労した開発者からの単なる追加。お気づきかもしれませんが、特定のリソースが存在しない場合に404、200、204のいずれを返すかは常に議論になります。上記の議論は、このトピックがかなり混乱し、意見に基づいていることを示しています(http-status-code標準が存在しますが)。個人的には、まだ言及されていないので、API定義でドキュメントをどのように決定してもお勧めします。もちろん、クライアント側の開発者は、特定の「REST」-apiを使用してRestに関する知識を使用する場合を念頭に置いており、APIがこのように機能することを期待しています。罠が見えると思います。そのため、どの場合にどのステータスコードを使用するかを明示的に定義するreadmeを使用します。これは、私がランダムな定義を使用するという意味ではありません。私は常に標準を使用しようとしますが、そのような場合を避けるために、使用法を文書化します。クライアントは、特定の場合にあなたが間違っていると思うかもしれませんが、文書化されているので、あなたと開発者の時間を節約するために追加の議論をする必要はありません。
Opsの質問に対する1つの文:404は、バックエンドアプリケーションの開発を開始することを考えたときに常に頭に浮かぶコードであり、Controllerメソッドが呼び出されないようにcontroller-routeに何か間違った構成をしました。そのことを念頭に置いて、リクエストがControllerメソッドでコードに到達した場合、クライアントは有効なリクエストを実行し、リクエストのエンドポイントが見つかりました。したがって、これは404を使用しないことを示しています。dbクエリが見つからない場合は、200を返しますが、本文は空です。
TL; DR:
/users/9
、404を返す必要があります。/users?id=9
、204を返す必要があります。ロングバージョン:
これらのステータスコードの私自身の使用法とこの投稿の例を確認した後、ユーザー#9がのURLで見つからなかった場合は、404が適切な応答であると言わざるを得ません/users/9
。
/users/9
今日の私のシステムでは、相関データがないときに404を返すことにしたため、Application Insightsログはログに記録された数百の404エラーでいっぱいになり、ログがすべて混乱します。ただし、これは、応答を設定するときにアプローチが正しくなかったことを意味するのではなく、ルーティングを設定するときにアプローチが正しくなかったことを意味することを提案します。
エンドポイントに大量のトラフィックが発生することが予想され、404エラーのログが多すぎることが懸念される場合は、ステータスコードを不適切に使用するのではなく、目的のステータスコードに一致するようにルーティングを変更する必要があります。
その後、コードに2つの変更を加えることにしました。
/users?id=9
結局のところ、APIのアーキテクトは、APIがどのように使用され、そのユースケースにどのようなルーティングが適切であるかを理解する必要があります。
の場合、/users/9
要求しているリソースはユーザー自体、ユーザー#9であると思います。「user」という単語が含まれるパスにたまたま存在する「9」として識別されるオブジェクトで応答するようにサーバーに要求しています。そのオブジェクトが見つからなかった場合は、404を取得する必要があります。
ただし、を呼び出すと/users?id=9
、要求しているリソースはユーザーコントローラーであると同時に、すべてのユーザーの完全なリストが返されないように、もう少し具体性を提供しているように感じます。クエリ文字列で定義されたID番号で識別できる特定のユーザーで応答するようにサーバーに要求しています。したがって、データが見つからなかった場合でも、データが見つからなかった場合でもコントローラーが適用されたため、204が適用可能であることが私には理にかなっています。
クエリ文字列アプローチは、API開発者だけでなく、クライアント開発者(特に、このコード、またはこのコードを呼び出すコードを継承するジュニア開発者や将来の開発者)にも役立つと思うことを実現します。
9はIDであり、任意の数ではないことが関係者にはすぐに明らかになります。この点は、このような基本的な例では意味がないように思われるかもしれませんが、GUIDを行IDとして使用するシステムや、人の名前でデータを取得できるシステム、または行IDの代わりに特定のZIP/郵便番号の情報を返すシステムを考えてみてください。 。関係するすべての開発者にとって、その識別パラメーターがIDではなく、名、姓、氏名、または郵便番号のいずれであるかが一目でわかると便利です。
このスレッド(執筆時点では26)の回答は、開発者が作業している構成のセマンティクスを理解することがいかに重要であるかを完全に示しています。
この理解がなければ、応答ステータスコードが応答のプロパティであり、他には何もないことは明らかではないかもしれません。これらのコードは応答のコンテキストに存在し、このコンテキスト外での意味は定義されていません。
応答自体は要求の結果です。リクエストはリソースに対して機能します。リソース、リクエスト、レスポンス、ステータスコードはHTTPの構成要素であり、HTTPに関する限り次のようになります。
HTTPは、表現の操作と転送(セクション3)を介して、リソースのタイプ、性質、または実装に関係なく、リソースと対話するための統一されたインターフェースを提供します(セクション2)。ソース。
つまり、応答ステータスコードの領域は、一部のターゲットリソースのみを考慮し、これらのリソースとの対話に使用されるメッセージを処理するインターフェイスによって制限されます。サーバーアプリケーションロジックは範囲外であり、操作するデータも重要ではありません。
HTTPを使用する場合、常にリソースとともに使用されます。リソースはエーテル転送または操作されます。いずれにせよ、私たちが量子の世界にいない限り、リソースは存在するか存在しないかのどちらかであり、第3の状態はありません。
(この質問のように)リソースの表現をフェッチ(転送)するためにHTTPリクエストが行われ、リソースが存在しない場合、応答結果は対応する404コードでの失敗を示すはずです。目的(表現をフェッチする)が満たされていません。リソースが見つかりませんでした。HTTPのコンテキストでは、結果を他に解釈することはできません。
RFC 7231ハイパーテキスト転送プロトコル(HTTP / 1.1):セマンティクスとコンテンツは、ここでは何度も参照されていますが、主にステータスコードの説明の参照として使用されています。HTTPインターフェースとそのコンポーネントのスコープとセマンティクスをよりよく理解するために、セクション#6だけでなく、ドキュメント全体を読むことを強くお勧めします。
応答コンテンツを共通の列挙型でエンコードします。これにより、クライアントは応答コンテンツをオンにして、それに応じてロジックをフォークできます。クライアントが「データが見つかりません」404と「Webリソースが見つかりません」404の違いをどのように区別するのかわかりませんか?誰かがユーザーZ /9を参照して、要求が有効であるかのようにクライアントに不思議に思わせたくはありませんが、データは返されませんでした。
204がより適切です。特に、Webサイトのセキュリティを確保するためのアラートシステムがある場合、404アラートの一部がバックエンドエラーまたは通常のリクエストであるが応答が空であることがわからないため、この場合の404は混乱を引き起こします。
w3によると、私は次のことを信じています。
2xx:
このクラスのステータスコードは、クライアントの要求が正常に受信され、理解され、受け入れられたことを示します。
4xx:
4xxクラスのステータスコードは、クライアントがエラーを起こしているように見える場合を対象としています。
クライアントがを要求し/users
、リストするユーザーがいる場合、応答コードは次のようになります200 OK
(クライアント要求は有効でした)。
クライアントが要求し/users
、データがない場合でも、応答コードはになります200 OK
。
要求されているエンティティ/リソースはユーザーのリストであり、リストは存在しますが、ユーザーは含まれていません(空のリストの方が良い204 No Content
と思いますが、空の応答が与えられた場合に使用できます)。
クライアント要求は有効であり、リソースは存在するため、4xx応答コードはここでは意味がありません。[]
一方、クライアントが要求し/users/9
、そのユーザーが存在しない場合、クライアントは存在しないリソースであるユーザーを要求することでミスを犯しました。この場合、。で答えるのは理にかなっています404 Not Found
。
410を使ってみませんか?これは、要求されたリソースがもはや存在せず、クライアントがそのリソースを要求しないことが期待されていることを示していますusers/9
。
410の詳細については、https ://www.w3.org/Protocols/rfc2616/rfc2616-sec10.htmlを参照してください。
応答にデータがないという理由だけで戻ってきた場合、404はどのクライアントにとっても非常に混乱します。
私にとって、本文が空の応答コード200は、すべてが完璧であることを理解するのに十分ですが、要件に一致するデータはありません。
このシナリオRuby on Rails
では、で応答し404 Not Found
ます。
クライアントが存在しないリソースを要求しました。だから、404 Not Found
より適切です。
このシナリオでは、多くの開発者がを好まないことがわかります404 not found
。
を使用したくない場合は404
、次の2つの応答コードのいずれかを使用できると思います。
使用する場合200 OK
:応答本文はempty json
:[]
または{}
使用する場合204 OK
:応答本文は空である必要があります。
私は404が正しい応答だとは思わない。
404を使用している場合、APIが見つからなかったこと、またはデータベース内のレコードが見つからなかったことをどのようにして知ることができますか?
あなたの説明から、あなたのAPIは問題なくすべてのロジックを実行したので、私は200OKを使用します。データベースでレコードが見つかりませんでした。つまり、APIの問題でも、データベースの問題でもありません。これはあなたの問題であり、レコードは存在すると考えていますが、存在しません。そのため、APIは正常に実行され、データベースクエリは正常に実行されましたが、何も返されませんでした。
そのため、このような場合は
200 OK
配列の場合は[]、オブジェクトの場合は{}のような空の応答を使用します。