Help us understand the problem. What is going on with this article?

WebAPIでHTTPステータス200と404、どっちを返せばいいのか迷った話

More than 3 years have passed since last update.

サブタイトル ~はじめてWebAPIを開発することになった僕が、返すHTTPステータスで迷った話~

この記事は株式会社アイスタイルアドベントカレンダーの6日目の記事です。

新卒1年目、業務ではWebAPIを開発している@YuyaAboが書きます。

迷ったこと

例えば、ブログサービスのAPIがあったとして、こんなシチュエーションを考えてみてください

  1. 存在しない記事が指定された articles/show/987654321
  2. 記事を検索したら無かった search/articles?id=987654321
  3. あるユーザーの書いた記事は0件だった articles/list/200
  4. 存在しないユーザーの書いた記事は0件だった articles/list/123456789

このとき無知な僕は次のように考えます。

「1の場合、記事がないんだから、HTTPステータスとしては404 Not Foundを返してあげるのが自然なはずだ!!!」

「2も1と同じように記事がないんだから404だよね」

「3も、ユーザーの書いた記事はなかったんだし、これも404かな・・・」

「4・・・これも3と同じでいいのかな・・・」

200と404の意味を考えてみる

まず僕は、HTTPステータスの200と404を理解することから始まります。

HTTPステータスの200と404は、下記の通りRFCで定義されていて、各種HTTPクライアントや実際にAPIを使う開発者は、下記の定義通りの意味で返ってくることを期待して実装を行います。

  • 200:OK リクエストが成功
  • 404:Not Found 指定したリソースが見つからない

次に、URI(APIエンドポイント)について考えてみます。

URIの意味を考えてみる

「URIはリソースを表している」ということを考えるととてもすっきりします。すると、最初に提示した4つの例は、以下のように考えることができます。

  1. 記事ID=987654321という記事が存在しないということは、articles/987654321というリソースが存在しないわけなので、404 Not Foundを返してあげる
  2. 1と同様に存在しない記事IDが指定されているけど、searchという単語が使われているようにこのAPIは検索のためのものであり、リソースそのものが存在しない1の場合とは異なるため、200 OKを返してあげる
  3. 指定したユーザーの書いた記事は0件だったけど、articles/list/200というリソース自体は存在するから200 OKを返してあげる
  4. 存在しないユーザーが指定されているので、1と同様articles/list/123456789というリソースが存在しないから404 Not Foundを返してあげる

(そもそもURIに「search」という単語を使うことについては、URIがリソースであるということを考えると少し特殊な気もしますが、このAPIは検索をするためのものです!ということが分かりやすく伝わるため、TwitterやInstagramのAPIでも「search」という単語が使われています。)

例:Twitter REST API

例として、実際に公開されているTwitter REST APIを上の4つに当てはめてみると以下のようになります。

  1. 指定したツイートを取得するstatuses/show/:idは存在しないツイートIDを指定すると404 Not Foundが返る
  2. ツイートを検索するAPIsearch/tweetsは、検索結果が0件だった場合も200 OKが返る
  3. 指定したユーザーがいいねしたツイートを取得するfavorites/listは、指定したユーザーにいいねが一つも無くても200 OKが返る
  4. 存在しないユーザーをfavorites/listで指定すると404 Not Foundが返る

まとめ

「200と404どっち返せばいいんだ・・・」と迷った場合は、URIはリソースであるということを意識し、さらにリソースが0件であることと、リソースがそもそも存在しないということを分けて考えることが重要だと思います。

そして、そのどちらに当てはまるかを考えると良いのではないでしょうか(0とnullの違いみたいな!)。

おわりに

今回はHTTPステータスの200と404で迷っていましたが、例えばQiitaのAPIでは、前回から更新されていないことを意味する304が使われていますし、実際にAPIを設計する際にはHTTPステータスについてもっともっと考えなければいけないことがあるでしょう。また外部公開のAPIなのか、内部向けのAPIなのかでも違ってくるはずです。

必要に応じてHTTPボディに適切な情報をくっ付けるなど、クライアント側にとって分かりやすいデータを返してあげることも大切ですね!

以上、読んでいただいてありがとうございました。明日のアイスタイルアドベントカレンダーは、@nirastamoさんです!!!

connehito
「人の生活になくてはならないものをつくる」というミッションの元、ママリを開発・運営する会社です。
https://connehito.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away