リソースが見つからない場合、204または404応答を返す必要がありますか?


15

トーナメントとスケジュールのためのシンプルなRESTfulサービスを開発しています。JSONボディを含むPOSTリクエストを通じてトーナメントが作成されると、トーナメントはに挿入さBiMapれ、DAO実装で次のように宣言されます。

private BiMap<String, Tournament> tournaments = Maps.synchronizedBiMap(HashBiMap.create());

トーナメントが作成されると、それに関連付けられた文字列IDが返されるので、ユーザーはそのトーナメントを将来参照することができます。彼/彼女は次のリクエストを実行して新しいトーナメントから情報を得ることができます:

GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39

しかし、そのようなIDのトーナメントが見つからない場合はどうなりますか?これまでのところ、204応答を返しています。まあ、ジャージーはnull、そのメソッドの1つから戻るときに私のためにそれをやっています。これは、上記のルートに対応するメソッドです。

@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Tournament getTournament(@PathParam("id") String id) {
    Optional<Tournament> optTournament = tournamentDao.getTournament(id);
    if (optTournament.isPresent())
        return optTournament.get();
    return null;
}

私の質問は次のとおりです。リソースが見つからなかったので、204: No Content応答を返すことは問題あり404ませんか、それとも代わりに応答でなければなりませんか?

それを404に変更する必要がある場合、明らかな質問:メソッドのシグネチャを変更する必要がありますか?これで(タイプTournament)のトーナメントが返されない可能性があるため、メソッドは異なるように見えるはずです。Response代わりに、型を戻り値の型として使用する必要がありますか?

回答:


32

HTTP 204何か見つかりましたが、空です。たとえば、http://example.com/logs/[date-goes-here]などのリクエストを使用して、HTTP経由でログファイルを提供しているとします。2015年5月18日:

  • http://example.com/logs/2015-05-19はを返しますHTTP 404。これは、ログがないことを意味します。これは、将来をログに記録することが難しいためです。

  • ただし、http://example.com/logs/2015-05-18HTTP 200は、応答のコンテンツにログエントリが含まれるHTTP 204か、ログファイルが作成されたが、このログがまだ記録されていない場合に戻ります。日付。

nullリクエストへの応答としてフレームワークに提供する場合、エントリが見つかったと想定され、このエントリは空HTTP 204です。代わりに、throw new NotFoundException();エントリが存在しないことをフレームワークに通知して、が生成されるようにする必要がありHTTP 404ます。

それを404に変更する必要がある場合、明らかな質問:メソッドのシグネチャを変更する必要がありますか?

いいえ、必要ありません。それがのいいところthrow new NotFoundException();です。メソッドの実際の戻り値の型が何であっても機能します。


5
RFC 2616に特に注意してください。メッセージ本文を完全に省略した場合のみ、204応答は仕様に準拠しています。ある程度、204応答のポイントは、「いいえ、コンテンツを返さなかったのは偶然ではない」と言うことです。MainMaの例をさらに詳しく説明します。ログルックアップツールがテキストファイルを出力する場合(たとえば、ログファイルをそのまま出力するログファイルの薄いラッパー)、204は空のログファイルに適しています。応答が空のJSONオブジェクト(例:)の場合{content: ''}、204応答は不適切です。
ブライアン

まあ、未来を記録するのは難しいから。」-このビットは任意の日付に依存します。読者が今日ではないふりをする必要のないものにしてみませんか?2015-02-29それはまったく存在しない日付なので、おそらく使用する方が良いでしょうか?
モニカの訴訟に資金を提供


1

あなたのリクエストはGET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39です。

http://localhost:8080/eventscheduler/エンドポイントとして存在しない場合は、404を返す必要/eventscheduler/があります。存在しないリソース()にアクセスしようとしています。これはクライアントにサーバーが存在することを示しますがlocalhost:8080eventschedulerエンドポイントには何もありません。

場合はhttp://localhost:8080/eventscheduler/エンドポイントとして存在しますが、必要なリソースが利用できない、5xxのエラーが適切です。これの良い例は、データベースがオフラインで、503を返す可能性がある場合です。もちろん、特定のインスタンスではなく、一般的な500エラーを返すこともできます。

場合はhttp://localhost:8080/eventscheduler/存在しますが、によって表されるものがc15268ce-474a-49bd-a623-b0b865386f39存在しない場合、私は内容を示すボディに200を返します。エンドポイントが存在し、行われた要求は完全に有効であり、処理できましたが、一致しませんでした。

エンドポイントへのクライアントのリクエストが有効でない場合、他の4xxエラーを確認します。クライアントがエンドポイントまたは401または403でリクエストされたアイテムへのアクセスを許可されていないことを示すか、400を使用してリクエストが無効であることを示すことができます。これらのいずれかを使用すると、応答本文で追加情報を提供できます。


エンドポイントとリソースを区別する必要はありません。URIがどのリソースに一致しない場合は、何らかの理由で、サーバーは404を返す必要があります
BDSL

正しいことをしているサイトの例については、このサイトの応答コードを確認してください。APIではなくWebサイトですが、同じhttp仕様が適用されます。softwareengineering.stackexchange.com/questions/266183385
bdsl 2018年

@bdsl私はそれが絶対に間違っているとあなたに言うことができます。たとえば、ユーザープロファイルを返すことができるユーザーサービスとやり取りしています。このエンドポイントがの/userように使用されているとしましょう/user?email=test@example.com。APIコンシューマーとして、/userなんらかの理由でサーバーに存在しない(APIのv2に追加され、サーバーがv1にあるか、v3で名前が変更された)か、または電子メールを使用しているユーザーかを知りたいtest@example.com存在しません。1つ目は404、2つ目は200で、本文にはそのメールアドレスのユーザーがいないことを示します。
Thomas Owens

@bdslいいですが、それが正しい、または最良であるとは限りません。また、Webブラウザーを介して人間が操作するように設計されたWebサイトと、ソフトウェアシステムで使用するために設計されたAPIを比較できないと思います。
Thomas Owens

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