HTTPステータスコードを適切に選ぶためのフローチャート : 難しく考えるのをやめよう

HTTPステータスコードを返すというのはとても単純なことです。ページがレンダリングできた?よし、それなら200を返しましょう。ページが存在しない?それなら404です。他のページにユーザをリダイレクトしたい?302、あるいは301かもしれません。

訳:HTTPのステータスコードのことは、市民ラジオの10コードみたいなものだと考えるのが好きです。「ブレーカー、ブレーカー、こちらホワイト・チョコレート・サンダー。200 OKを受信した。」

人生は至福のものです……そう、誰かが「RESTに則ってないじゃないか」と言ってくるまでは。やがて、あなたの新しいリソースが、Roy-Fieldingが承認したRFC準拠のステータスコードを返しているかどうか知らなければならなくなり、そのために夜も眠れなくなることを思い知るでしょう。これはただの200でいいのだろうか?それとも本当は204 No Contentだろうか?いや、明らかに202 Acceptedか……ひょっとして201 Createdだろうか?

事態をややこしくしているのが、HTTP/1.1のガイドライン(つまりRFC)が最初に書かれたのが1997年であるということです。1 33.6kbpsのモデムで、Netscape Navigaterでサイバーウェブをサーフィンしていた頃です。これでは、孫武の『孫子』を現代のビジネス戦略に適用しようとするようなものです。時代を超越したアドバイスであるとはいえ、正直に言って、「孫子の5つの火攻めの兵法を、どうやってマーケットのバリデーションに使えばいいのか」なんて、未だかつて分かったことがありません。

win98-rfc2068-annotated

「自分の状況に関係あるステータスコードを即座に判断できるような視覚的な決定木があって、不適切な/時代遅れのステータスコードを除外出来たらいいのになあ……」

どういたしましてインターネット。その日は来ました。

はじめに

StatusCodes

これはばかばかしいほどに当たり前のようにも見えますが、「これは503 Service Unavailableだろうか、それとも404 Not Foundだろうか?」という疑問に迷い込む人を過去に多く見てきました。ちょっと待ってください。もしもあなたが「2つの特定のステータスコードのうち、どちらを選ぶか」について悩んでいて、その2つが完全に別の分類だった場合、その悩み方は間違っています。立ち戻って、上のフローチャートを見てください。

分類ごとに特化したフローチャートに入る前に、いくつか注意があります。

  • 私のいう事を全部信じる必要はありません — RFC 7231httpstatuses.com を読みましょう。
  • 私が想定している読者は、ウェブサイトやREST APIを作ろうとしている人です。
    • Webサーバの実装に特化したレスポンスコードについては言い紛らわしています。
    • (そして、プロキシサーバに関するレスポンスコードの話は完全に省いています)
  • 私は、レスポンスコードを3つの大まかなカテゴリに分類しました。
    Categories

最後ですが重要な免責事項を。私はこの記事を書くための特別の資格を持った人間ではありません。日々有用なAPIを作ろうとしているRackburgのオフィスで働いており、いくらかRFCを読んだという、ただそれだけの人です。もしあなたがこれを読んで、私が間違っていると思ったり、あなたの好みのステータスコードが軽んじられていると思ったりしたら、それは私が愚かだからです。その際は、どう間違っているかを私に詳しく教えてください

2XX/3XX

2xx3xx

4XX

4XX

5XX

5xx

最後に: 「なぜステータスコードが重要なのか?」について

私はこの点について完全に確信があるわけではありません。

Facebookには賢い人がたくさんいますが、彼らの提供するAPIには200しか返さないものがあります。

特定のステータスコードを悩ます基本的議論は、「既存のステータスコードは、モダンなwebサイト/APIで使うにはあまりに一般的過ぎる」というものです。もし、クライアントが何らかの有意義な方法でレスポンスを取り扱えるようにするため、アプリケーションに特化した形式の詳細をレスポンスに含めなければならないのであれば(例えば「どのフィールドがバリデーションに失敗したか、そしてそれはなぜか」など)、それほど有用でもなく冗長なHTTPステータスコードを心配するのに時間を費やすのは何故なのでしょう?

特定のステータスコードを使うべき理由について、よく引用される一般的な理由は、「HTTPはレイヤー化されたシステムであり、クライアントとサーバの間に存在するプロキシ・キャッシュ・HTTPライブラリがうまく動くにはステータスコードが有効であることが必要だから」というものです。しかし、この意見は、「全ての人がHTTPSに乗り換え、サーバが直接コントロールしていないキャッシュノード/プロキシが禁止されるようになる」といった状況にでもならない限り、従わなければならないほどのものではないと思います。

代わりに、私が「それでも、なぜステータスコードが重要なのか」と考える理由を3つ挙げます。

  1. クライアントが、既に異なるステータスコード毎の特殊な動作を扱っている(あるいは、容易に扱えるように拡張できる)
    • 301 Moved Permanently302 Found とでは、GoogleなどのSEOでの意味合いが変わってきます。
    • 301 Moved Permanentlyはキャッシュ可能であることを含意していますが、429 Too Many Requestsはキャッシュ不可能であることを含意します。他のステータスコードについても同様の違いがあります。
    • クライアントのライブラリでは、 429 Too Many Requests に対して、「一度リクエストをやめて、少し待った後に再びリクエストを試す」といった対応ができます
    • 503 Service Unavilable も同様
  2. モダンなケースでの要求事項に完全に対応できるわけではないものの、多くのステータスコードは特殊なレスポンスとして対応するに値するケースを表現できています(標準コードを使ってはいかがでしょう?)
    • 405 Method Not Allowed を返すべきところで 404 を返すAPIを見ると、「URLを間違えたかな?それとも間違ったHTTPメソッドを送ったかな?」という疑問に悩まされてしまいます。
    • 500 Internal Server Error と混同されることなく、正しい 502 Bad Gateway (アップストリーム側の問題)がきちんと返されていれば、デバッグにかかる時間はもっと短くなったことでしょう。
  3. 信じる信じないはともかく、201 Created429 Too Many Requests503 Service Unavilableといったステータスコードを返す慣習は、広く使われるAPIの間でも確立されています。この慣習に従えば、あなたのWebサイト/APIはユーザにとってぐっと使いやすくなり、遭遇した問題のトラブルシューティングも容易になるでしょう。

一番難しかったのは、どのコードを返すべきか決定することでした。しかし、正しい知識(つまり、そうですね、フローチャート形式などでしょうか)さえあれば、有効なコードを返すことはとても容易になります。

こちらもあわせて

脚注


  1.  RFC 2616のことは気にしないでください(さらにひどいのは2068です)。 見るべきRFCは7231です。