先日東京へ行ってきたんですが、なんとなく持っていった HTTP ステータスコード百人一首で遊んできました。

そこには Web エンジニア以外の方もおり、そもそもステータスコードって何よ?どう使い分けるの?みたいな話が出ました。
そこで今回は Web API で利用することを想定して、個人的によく使うコードと利用シーンを考えてみます。

そもそも HTTP ステータスコードって?

Wikipedia によると「HTTPにおいてWebサーバからのレスポンスの意味を表現する3桁の数字からなるコードである。」とあります。
このステータスコードは用途ごとに異なる値が設定されており、特に上位1桁がどの数字かによって意味が大きく変わります。
普段ブラウザでページを閲覧したりファイルをダウンロードする際も、原則何かしらのステータスコードがサーバから返されています。

よく使うコードと利用シーン

101 Switching Protocols

WebSocket など HTTP 以外のプロトコルで通信する場合に利用します。
ただ、明示的に設定することはほとんどありません。

200 OK

処理が成功した場合は原則このコードを返します。
明示しなくとも、既定でこのコードを返してくれるようなフレームワークも多いです。

201 Created

リソースの新規作成(ユーザ登録など)が成功した場合にこのステータスコードを返します。
Wikipedia には「新たに作成されたリソースのURIが返される」とありますが、Web API では作成されたリソースの情報(識別子など)を返すことが多いです。

204 No Content

リソース削除など「処理は成功したがレスポンスが特にない」場合に利用します。
削除以外でも、上記ケースに該当する場合 200 の代わりに利用することもあります。

301 Moved Permanently

別のサイトにリダイレクトすることをクライアントに教えるために利用します。
サイト移転など「恒久的に移動した」場合に利用します。

302 Found

301 同様別の URL にリダイレクトすることをクライアントに教えるために利用するんですが、こちらは一時的な移動をあらわす場合に利用します。
ただ、データ登録後一覧にリダイレクトする場合も長らくこのステータスコードが使われており、上記ケースと差別化するために 303/307 というステータスコードが作成されたようです。
前者は 303、後者は 307 を利用するようですが、Web フレームワークだと今でも 302 を使うものが多い気がします。

304 Not Modified

リクエストしたリソースが更新されていない場合に返します。
このステータスコードが返された場合、サーバから新しくリソースをダウンロードしません。
開発中はあまり意識しませんが、ブラウザでの通信時などは If-Modified-Since ヘッダを利用して更新判定がされ、気づかないうちに 304 レスポンスが返されていたりします。

400 Bad Request

クライアントのリクエストが不正な場合に利用します。
バリデーションエラーで利用することが多い印象です。

401 Unauthorized

ログイン失敗など認証エラーをクライアントに教えるために利用します。

403 Forbidden

認証は完了しているがページやリソースへのアクセス権限が存在しない場合など、認可エラーをクライアントに教えるために利用します。

エンジニアでなくともインターネット老人会員なら知っているコードその1です。
あなたにはこのファイルにアクセスする権限が無い。

404 Not Found

リクエストした URL やリソースが存在しなかった場合に利用します。

エンジニアでなくともインターネット老人会員なら知っているコードその2です。
あなたがお探しのファイルは見つかりませんでした。

405 Method Not Allowed

許可されていないリクエストメソッドでアクセスがあった場合に利用します。
GET メソッドを許可している /hoge に POST メソッドでアクセスがあった場合などです。

409 Conflict

リソースの競合をクライアントに教えるために利用します。
例えばある会員システムがメールアドレスを識別子としていた場合、すでに登録されているメールアドレスで登録しようとしたユーザに対してこのエラーを返します。

412 Precondition Failed

前提条件失敗時に利用します。
時刻やバージョン、If-Unmodified-Since ヘッダなどを利用した楽観ロックによるリソース更新失敗時などで利用します。
AさんとBさんで同じリソースを更新しようとした場合、後で更新した側にはこのエラーを返します。

414 URI Too Long

URI が長すぎる場合に利用します。
GET メソッドを利用したリクエストの場合パラメータは URI に含まれるので、検索機能などで条件が多岐にわたる場合にこのエラーが起きることがあります。
一応 GET 以外のリクエストメソッド(POST など)でリクエストし、リクエストボディにパラメータを含めればエラーにはなりませんが、これは色々と悩ましいところです(今回の趣旨とははずれるので割愛します)。
上記のような問題を解消するべく QUERY というリクエストメソッドも検討されています。

500 Internal Server Error

内部サーバーエラーです。
大抵はアプリケーション内部で(コードによるバグやデータベースとの通信エラーなど)何かしらのエラーが起きています。
バグが起きている場合は速やかに修正しましょう。

502 Bad Gateway

プロキシ先にリクエストを拒否された場合に利用します。
例えば nginx -> アプリケーションという経路でリバースプロキシを設定していた場合、アプリケーション側へ到達できなかった場合にエラーになります。

503 Service Unavailable

一時的にサービスが利用できなかった場合に利用します。
メンテナンスや一時的なシステムダウンなどで利用します。

504 Gateway Timeout

プロキシ先のレスポンスを受け取れなかった場合に利用します。
例えば nginx -> アプリケーションという経路でリバースプロキシを設定していた場合、アプリケーション側から指定時間以内に nginx にレスポンスが返ってこなかった場合にエラーになります。

まとめ

駆け足でよく使うステータスコードと利用シーンをまとめました。
「他にもこんな使い方あるよ」とか「こんな使い方しないだろ、常識的に考えて…」というツッコミがあればぜひ教えてください。