「結果なし」はRESTfulレスポンスのエラーになりますか?


52

例について説明します
。パン屋のAPIの作成を開始します。APIを使用すると、ユーザーはを使用して自家製ミントチョコレートチップクッキーなどのベーキング製品のカタログを検索できますapi.examplebakery.com/search?q=.....

誰かがこれを使って名前の付いた製品を探しますが、pineapple-banana flavoured cookies明らかに結果が見つかりません。

これはエラーとして返されるべきですか?検索は失敗せず、APIが検索し、Cookieが見つからないという結論に達しました。404APIが実際に見つかったため、APIはを返すべきではありません。



6
可能性のある重複したRESTfulなAPIは事の不在を表す
ブヨ

3
@gnat:これは重複ではありません。他の質問は特定のリソースに関するものであり、複数のリソースに対するクエリではないためです。
グレッグブルクハート

7
同様に、オブジェクトの配列を返す関数があるとします。特定のユースケースに一致するオブジェクトがない場合、例外を介して関数を実行するか、空の配列を返しますか?
ケビン-モニカの復活

2
@AakashM GETリクエストにHTTP-204を返すことは非常に珍しいことで、どこにも見たことがないことは知っています。私の知る限り、HTTP-204は通常、サーバー上のリソース(POST / PUT / DELETE要求など)を変更するときの応答として使用されます。
ラドゥマーゼア

回答:


122

結果がある場合、出力は(コメントに基づくJSON)リストです。結果のないクエリの場合、出力はまったく同じである必要があります。リストsimpleには、0個のアイテムが含まれています。

だからあなたの応答が通常これなら:

{
    "results": [
        {
            "name": "Pancakes",
            ....
        },
        {
            "name": "French Fries",
            ....
        }
    ]
}

次に、結果が0のクエリの場合、次のようになります。

{
    "results": []
}

結果の「ページ」の数、それらの「ページ」へのリンクなどに関するメタデータも含める場合は、「ページ」が1つあると言うことをお勧めします。

HTTPステータスは、結果がある場合と同じである必要があります- 200 OK

204 No Contentオプションのように思えるかもしれませんが、実際には「コンテンツ」、つまり空のリストを返すためではありません。空のリストが「コンテンツ」としてカウントされないと感じた場合、つづりの提案を提供するために応答を修正したらどうでしょうか。応答の中核はまだ空のリストですが、今ではさらに「コンテンツ」があります。

HTTPステータスコードに関するより有用な情報については、jpmc26の回答を読む価値があります。


9
これは、ヌルオブジェクトパターンと同じ種類の考え方です。エラーとnullは、ここに何もないと言う唯一の方法ではありません。静かに何も表現しないこともあります。そうすれば、クライアントは何もテストする必要がありません。
candied_orange

54
あなたがコンテンツを返しているので、204を返すことは不適切であると主張します。コンテンツに結果がないというだけです。これは、コンテンツをまったく返さないこととは異なります。
TMN

9
@TMNは同意しました-「結果なし」には204は適切ではありません。クエリは常に配列を返し、結果は配列内にあります。結果がない場合、クライアントはそれを自然に処理します。クライアントが特別なテキスト(「結果が見つかりませんでした」)を表示したい場合は、問題ありません。204は、自然に結果を返さないエンドポイントに対してのみ返される必要があります。
ジェイソンB

1
あなたは空の文字列I偵察としてシリアルnullを返した場合は、204を使用することができます
ユアン・

15
この。RESTful APIを構築する際に重要なことは、restfullnessではなくAPIの部分です。優れたAPIは、クライアント/消費者の生活を楽にします。空の配列は、null値/例外/ステータスコードよりも簡単に処理できます。
グラン

37

HTTPコードを決定するときは、常に次の質問をする必要があります。

任意のクライアントが応答でできること/すること/すべきことは何ですか?

  1. クライアントは常に応答を失敗として扱うべきですか?次に、問題がクライアントの入力であるかサーバーのプロセスであるかに応じて、4xxまたは5xxが必要です。
  2. クライアントは代わりにどこかでリクエストを行う必要がありますか?その後、3xxはあなたのためです。
  3. サーバーは、クライアントが要求した(成功した)ことをしましたか?それは2xxです。

応答コードが最初に含まれる範囲を常に決定してください。そうすることで、オプションとしての多くの応答コードが不要になり、(さらに重要なことですが)コードのセマンティクスに従うことがはるかに簡単になります。コードの各カテゴリが表すものの説明については、HTTPコードのドキュメントの最初のセクションを参照してください。

この場合、クライアントは、有効な既存のエンドポイントからフィルターを与えられた結果のリストを要求し、それにアクセスするための承認を持っています。サーバーは要求を処理し、返す適切なデータ(アイテムなし)を決定できたため、要求は成功しました。彼らが与えたフィルターがすべての結果をフィルターで除外したということが起こります。これは一部のクライアントにとって期待される結果になる可能性があるため、これがクライアントが望んでいたものかどうかを判断するのはサーバー次第ではありません。クライアントコードにとってなんらかの問題がある場合、適切に判断、確認、処理するのはクライアントの責任です。したがって、これは明らかに2xxです。

質問は、「2xxはどれですか?」です。これは、サーバーの応答方法によって異なります。

  • 他の回答で説明されているように、空のリストの表現を送り返しますか?その場合、200が必要です。200は、サーバーで問題が発生せず、クライアントが消費する結果の表現があることを意味します。これはおそらく、結果があるかどうかに関係なく応答を解析し、空のリストを自分で処理する方法を見つけることができる消費者に応答する最も便利な方法です。
  • ここでは、204は意味的に間違っていません、メッセージ本文なしで応答する必要があります。これは、すべてのクライアントコードが異なるHTTPコード(または、少なくともメッセージ本文の欠如)を明示的にチェックし、それらを個別に処理する必要があることを意味します。これは不便であり、クライアントの振る舞いが悪くなる可能性が高くなります。

その他はまったく適用されません。

  • 201は問題外です。永続的なリソースを作成しておらず、作成したリソースに場所を返していません。
  • 202は問題外です。要求が完了しました。バックグラウンドで処理されていません。
  • 203は、権限のあるサーバーとクライアントの間で応答が変更されたことを意味します。RESTfulインターフェイス権限のあるサーバーであるため、ここでは当てはまりません。
  • 205は意味がありません。クライアントが何かを消去または更新する必要はありません。
  • 206は、複数の応答で大きなリソースを返すように設計されているようです。また、クライアントが要求することを尋ねる内容の一部のためにヘッダに(クエリ文字列を経由して改ページが対象となりませんので)。ここでは適用されません。

したがって、200または204のいずれかである必要があり、200はより単純で堅牢なクライアントコードにつながる可能性が高くなります(特に、空のリストを含む一貫した応答構造を使用する場合)。


5
downvoterの意見に興味があるでしょう。議論の余地があるとは思わない。
jpmc26

2
クライアントが204を明示的にチェックする必要はないと思います。必要なのは、null応答オブジェクトを処理する機能だけです。「本文の解析」部分をスキップして204を処理するのは、HTTPフレームワークの仕事です。Content-Lenght 4とbody nullの 200 はまったく同じです。
Agent_L

1
@Agent_Lサーバーが通常の応答と矛盾する構造(null通常はリストがある場所に置くなど)で応答する場合、200であっても一貫性の利点を享受しないことは正しいです。しかし、私が説明するのは通常の構造と一貫性があり、結果のリストが通常表示される空のリストを持つ応答。204は、そのような一貫した応答を行う機会を奪います。また、便利な機能を備えたHTTPクライアントライブラリでも、JSONを解析するための明示的な呼び出しを頻繁に(通常は?)行う必要があります。
jpmc26

@Agent_L特にリストでは、呼び出し側はコードを空のリスト上で普通に実行させることができます(たとえば、ループすることで)。一方、別のタイプの表現を処理するには何らかの種類の明示的なチェックが必要です。
jpmc26

16

いいえ。404を使用して「クエリは処理されましたが、一致しなかった」ことを示すのは、次の理由によりひどいです。

  • 例外処理に基づく条件付きフロー(つまり、例外的でない結果を強制して、パフォーマンスが悪く扱いにくいクライアントで例外を作成および処理します)

  • 「実際の」ページ間の曖昧さが見つかりませんでした。エンドポイントに間違ったエラーを入力しました

覚えておくべきことは、メッセージをデシリアライズするクライアントが常に存在し、そのクライアントが返すものが重要であることです。シリアル化ではありません。

クライアントがnullを返す必要がある場合は、nullのシリアル化を使用します。クライアントが空の配列を返す必要がある場合は[]を使用し、クライアントがエラーをスローする場合は500を使用してエラーメッセージを渡す


2
なぜサーバーは、クライアントが情報で何をしているのか気にする必要があるのですか?(PS:私はあなたの答えを否定した人ではありません)。
ラドゥ・ムルゼア

このコンテキストでは、「クライアント」は、クライアントアプリケーションにサービスを公開するクライアントデバイスで実行されるコードです。サービスのメソッドを公開し、サービスの意図どおりに結果を返すことができる必要があります。あなたはすべての機能への通信のためのクライアントサーバペアが必要
ユアン・

3
もちろん、クライアントエラーに5xxを使用しないでください。その場合は4xxをお勧めします。
ケビン

1
しかし、これらのインスタンスのほとんどで「クライアント」ではなく「サーバー」であるべきではありませんか?リクエストを処理し、応答を提供しているのはサーバーです。クライアントは単に応答を処理しますか?どの場合、クライアントエラーではなくサーバーエラーであるため、5xxコードで問題ありませんか?
MrWhite

2
トラブル、すべてのエラーコードは、彼らは、HTTPの中に意味を持つということです。500は、あなたのサービスが例外をスローする場合に適しているだけのコードです
ユアン・

9

@Ewanの非常に良い答えを超えて:

クエリが結果のセットを返す種類である場合、空のセットは論理的には1つまたは複数のセットと同じくらい適切です。一般的に、@ Ewanが述べている理由から、空のセットをエラーに変更することは害よりも害が大きく、単に不要です。

クエリが特定のシングルトンを検索して返す種類(たとえば、IDによる完全一致など)を返す場合、論理的に適切な応答は見つかりません。


うん、私はユアンの答えでそれを正確に考えました。
ウォルフラット

5

データが返されない場合、コードは特別なアクションを実行する必要があると想定していますが、そうでない場合もあります。コードは単に製品数を探しているか、結果をリストまたは任意の数に追加しているだけかもしれません。実際にエラーがある場合にのみ、ユーザーに「エラー」を与える必要があります。


3
「実際にエラーが発生した場合にのみ、ユーザーに「エラー」を与える必要があります。」- この。「検索」を実行する際の空の結果セットは、通常「エラー」ではありません。ただし、データベース接続が失敗し、検索を実際に実行できなかった場合、空の結果セット(エラーなし)はあいまいになります。この場合、何らかの種類のエラー状態が適切です(おそらく、空の結果セットとともに-APIの定義方法によって異なります)。
MrWhite

0

APIを使用する場合、クライアントとして「エラー」ケースとは異なる「成功」ケースを処理する必要があります。私には選択肢がありません。したがって、クライアント異なる扱いをしたい状況ではエラーを返し、クライアント同じ扱いをしたい状況では成功を返す必要があります。

理論上、0、1、200などの任意の数の結果を返すクエリを実行する場合、APIがすべての結果の完全なリストを提供するたびに「成功」​​を返す必要があります。そしておそらく、多くの結果がある場合には、過剰なサイズを避けるために結果の部分的なリストを返して、他の結果を取得する方法が合意されています。それは、クライアントとして、私はしばしば、より多くの結果の場合のように結果がゼロの場合を扱いたいからです。違う扱いをするかもしれませんが、強制されたくはありません。

値を検索する場合は異なります。ちょうど1つの結果、つまり探している値を期待しています。そして、私がやりたいことを意味のある方法で続けるために、その結​​果が必要です。ここでは、値が存在しない場合にステータス404を返す方がはるかに受け入れられます。とにかくそのケースを異なる方法で処理する必要があるからです。

要約:クライアントがゼロから大きな数までの任意の数の結果を期待している場合、すべての結果が配信されていれば、数がゼロであっても「成功」を返します。クライアントが結果を1つだけ期待している場合、結果が見つかった場合は成功を返し、結果が見つからない場合はエラーを返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.