よしたろうブログ

駆動設計・アーキテクチャ・変更容易性とかの話が好きです。

HTTPとRESTの基本 『網羅版:HTTPメソッドとレスポンスコード』

初めに

各文献を元にまとめした。『3. HTTPレスポンスコード概要』以降は引用まんまに近いところもあれば、大幅に書き換えた・再構成した部分も多々あります。

この記事を書こうと思った切欠はステータスコードについて質問された時にちゃんと答えられなかったからです。 非常に疲れましたが、とても理解が進みました。
これを元に、次は RESTful API の設計の記事とか書いてみようと思います。

以下から本文です。

1. HTTP・TCP / IP・RESTの基本

HTTPはTCP/IPをベースとしたステートレスなプロトコル。現在 HTTP 中核仕様( RFC 9110 ) で規定されています。

HTTP( Hypertext Transfer Protocol )は名前こそハイパーテキストの転送用プロトコルですが、 実際には HTMLやXMLなどのハイパーテキストだけではなく、静止画、音声、動画 JavaScript プログラム、PDFや各種オフィスドキュメントファイルなど、コンピュータで扱えるデータであれば何でも転送できます。

HTTP は REST の重要な特徴である統一インタフェース、ステートレスサーバ、キャッシュなどを実現している、 Web の基盤となるプロトコルです。

1-1. 全ては〇〇である、という抽象化

全ては〇〇である、という抽象化をRESTは実現しています。RESTにおいて「全てはURIである」と定義し、「GET」なら取得、「POST」なら作成、「PUT」なら更新、「DELETE」なら削除のように多種多様なリソースへの操作、処理をたった4つの動詞で表現し、また制約しています。

他での分野でもその特徴は見られます。

  • 全てはファイルである(UNIX
  • 全ては関係・集合である(RDB/SQL

多様なものを同じ仕組みで表すために強い制約・抽象化を行い単純化しインターフェスの振る舞い・実行できることを少なくし、統一的に提供することで再利用性と再接続性を高めているわけです。

誰がクライアントで、何が接続先で、レガシーなシステムであろうと、RESTに則っていればWeb上の全リソースの指定・操作を「GET」「POST」「PUT」「DELETE」で誰でも実行可能になるのです。

引用元:HTTP 意味論(共通基盤)RFC 9110 — HTTP Semantics

HTTP 要請のターゲットは、 リソース と呼ばれる。 HTTP は、リソースの資質を制限しない — 単に,リソースとやりとりするときに利用できるインタフェースを定義するに過ぎない。 各リソースは、 URI ( Uniform Resource Identifier )により識別される。

1-2. REST(REpresentational State Transfer)

  1. 統一されたインターフェース 同じリソースに対するすべてのAPIリクエストは、リクエストの送信元に関係なく、同じように見える必要があります。 REST APIは、ユーザーの名前や電子メール・アドレスなど、同じデータが1つのURI(Uniform Resource Identifier)だけに属するようにします。 リソースは大きすぎてはいけませんが、クライアントが必要とする可能性のあるすべての情報が含まれている必要があります。

  2. クライアントとサーバーの分離 REST APIの設計では、クライアント・アプリケーションとサーバー・アプリケーションは互いに完全に独立している必要があります。 クライアント・アプリケーションは要求するリソースのURIのみを知っていればよく、他の方法でサーバー・アプリケーションと対話することはありません。 同じく、サーバー・アプリケーションは要求されたデータをHTTPを介して渡すのみで、クライアント・アプリケーションを変更することはありません。

  3. ステートレス性 REST APIはステートレスです。つまり、各リクエストには、その処理に必要なすべての情報を含める必要があります。 言い換えれば、サーバー側のセッションは不要ということです。 サーバー・アプリケーションは、クライアント・リクエストに関連するデータの保存を許可されていません。

  4. キャッシュ可能性 キャッシュが許可されている場合は、クライアント側またはサーバー側でリソースのキャッシュが可能である必要があります。 サーバーの応答には、配信するリソースのキャッシュが許可されているかどうかに関する情報も含まれている必要があります。 これにより、サーバー側のスケーラビリティーが向上すると同時に、クライアント側のパフォーマンスも改善します。

  5. 階層化されたシステム・アーキテクチャ REST APIでは、呼び出しと応答は異なる階層を通過します。 これまでの経験から、クライアント・アプリケーションとサーバー・アプリケーションが互いに直接接続していると想定してしまうのは誤りです。 通信ループには、さまざまな中間システムが存在する可能性があります。 REST APIでは、クライアントとサーバーのいずれも、エンド・アプリケーションと中間システムのどちらと通信しているのかを判別できないように設計する必要があります。

  6. コードオンデマンド(オプション) REST APIは、通常、静的リソースを送信しますが、場合によっては、応答に実行可能コード(Javaアプレットなど)を含めることもできます。 その場合、コードは必ずオンデマンドで実行する必要があります。

1-3. リソース指向アーキテクチャROA(Resource Oriented Architecture)

ROA内のものはすべて RESTful であると見なされる。だが、REST は アーキテクチャでなく、一連の設計条件であり、「REST アーキテクチャ」というも のは存在しない。REST はきわめて一般的な設計条件であり、 特に Web と結び付いているわけではない。

ROAは、それ自体を参照するに値するものを「リソース」として定義し、リソースを中心に考えるアーキテクチャのこと。リソースという概念、リソースはURIを持つ(URI)、リソースに対する操作(統一インターフェース)、リソースの表現形式(表現)、というようにリソース指向の中心はあくまでリソースになる。

Web API を RESTful にするとは、 ROA に沿って設計することにほかなりません。したがって、この ROAの概念と特徴について正確に理解しておく必要があります。ROA はRESTful APIを実装するうえで問題を解決してくれるアーキテクチャです。言い換えるとRESTful APIROA の実装ということになります(ROA に則り RESTful API は実装されている)。

1-3-1. リソースがリソースであるための条件

リソースは少なくともURI を1つ持っていなければなりません。 URIはリソースの名前とアドレス。 URI を持たない情報はリソースではなく、ほかのリソースを説明するデータとして以外に、Web上に存在することはありません。

1-3-2. URIとリソースの関係

2つのリソースが同じであることはあり得るか。 2つの URL が同じリソースを表すことはあり得るか。 1つの URI が2つのリソースを表すことはあり得るのか。

定義上、2つのリソースが同じであることはありえない。それらが同じであるならば、リソースは1つしか存在しないはずである。ただし、何らかの時点で、2つの異なるリソースが同じデータをポイントすることがある。

例えば、以下の2つはしばらくの間は同じファイルを指している。  /software/releases/1.0.3.zip  /software/releases/latest.zip

だが、これら2つのURIの目的は異なる。 一方のURI は常に特定のバージョンをポイントし、もう一方のURIはクライアントがアクセスした時点で最新のバージョンをポイントする。 これは2つの概念であり、2つのリソースであるため問題はないとされます。

リソースはURIを1つ以上持つことができるため、本当に同じリソースに2つ以上のURIが結びつくこともある。 こういったリソース が複数のURI を持つ場合、クライアントはリソースを参照しやすくなるが、結びつくURIが増えるたびにURIの価値が希薄化してしまいます。クライアントによって使用する URI が 異なると、すべてのURI が同じリソースを参照することを自動的に証明する方法がないからです。

これを回避する方法の1つとして、同じリソースに対して複数のURIをサポートし、そのうち1つをそのリソースの正規URIにするという方法が考えれる。クライアントが正規URIをリクエストしたら200(OK)とともに適切なデータを送信する。他のURI(正規でないURI)をリクエストしたら正規URIとともに303(See Other)を送信する。こうすることで正規URIにリダイレクトさせることができる。

もう1つの方法は、すべてのURI を同じものとして公開するが、非正規 URI がリクエスト された場合に、 Content-Location レスポンスヘッダーで「正規」 URI を渡す方法。出来るなら、URIが指し示すリソースは単一である方が変更が容易で、使用しやすい。

レスポンスコード303や Content-Location レスポンスヘッダーについては後述しています。

また、詳細は割愛しますが、ROA における4つの概念として以下があります。当然の様な性質ですがこれは ROA によるものだったんですね。 1. リソース 2. 名前 (URI) 3. 表現 4. リソース間のリンク

1-3-3. ROA における4つの特性

  1. アドレス可能性
    最も重要。 URIを通じ、リソースを端的に指し示すことができる性質。 すべての情報が一意なURIで表現されるようにすること。これが無いと接続性と統一インターフェースは実現できません

  2. 接続性
    あるリソースに「別のリソースへのリンク」を含めることができ、リンクを含めることで「別のリソースに接続すること」ができること。

  3. 統一インターフェース
    リソースの取得、作成、更新、削除といった操作は、すべてHTTPメソッドを利用すること。「GET」なら取得、「POST」なら作成、「PUT」なら更新、「DELETE」なら削除のようにリソースへの操作、処理を指定。上記2つの性質が保証されて初めて価値の出る性質。

    またHTTPメソッドの利用 がROAに沿っていれば、 安全性 (Safety) とべき等性 (Idempotence) を持つようになっています。 安全性 (Safety) とはサーバ側の状態を変更しない性質のことで、通常はGET や HEADメソッドでの操作が該当します。 冪等性 (Idempotence) とはその操作を何度繰り返しても同じ状態となる操作のことで、 GET / HEAD / PUT / DELETE メソッドがその性質を持ちます。

    安全性と冪等性については後日の記事で詳細を説明します。

  4. ステートレス性
    すべてのHTTPリクエストが完全に分離している性質であり、セッションなどの状態管理は行われないこと。クライアントが送信するHTTPリクエストには、サーバがそのリクエストを処理するために必要な情報が全て含まれており、以前のリクエスト情報にも依存しない。もちろんCookie等でセッション管理も行わない。

    逆に分離・独立していない場合はステートフル。「HTTP Cookie を用いたセッション管理を行っているため直前のリクエストで変更された状態をサーバ側が把握しており、次の HTTPリクエストはその前のリクエストを行っていないと実行できない」といったケースはステートフルです。

1-4. リソースとは

Web上に存在する、 名前を持ったありとあらゆる情報 Webサーバはリソースを特定の言語(英語、日本語)やフォーマット(XMLJSON)で送信しなければならない。こういったリソースの形式を『リソースの表現』と呼ぶ。

  1. 世界中のResources は、 URIで一意の名前を持つ。全てのリソースはURIで表現する。URIがリソースそのものを⽰す。
  2. URI とは 「Uniform Resource Identifier」 の略。統一リソース識別子といい、 Resourcesを識別するID
  3. URIを用いることで、プログラムは リソースが表現する情報にアクセス可能 (アドレス可能性)

ex.http://www.example.com:8080/news/index.htm?page=2&msg=yes#hot

  • https:
  • //
  • www.example.com
    • ホスト(host)アクセス先サーバー名
  • :8080
    • ポート(port)アクセス先サーバーのポート番号
  • /news/index.htm
    • パス(path)指定したオーソリティの中でのアクセス先を指定。サーバーの公開領域内でのディレクトリ名とファイル名で。
  • ?page=2&msg=yes
    • クエリ(query)パスの中でさらにアクセス内容を細かく識別。サーバー上で動作するプログラムへの指示や命令が書かれることが多い。
  •  #hot
    • フラグメント(fragment)アンカーと呼ばれることも。主となる内容に加えて部分や代替表現を指定。通常はサーバーには伝えられず、サーバーから送られた情報をクライアント(ブラウザ)が処理する際に使う。

1-5. URIとURLとURN

UniformResourceIdentifier :統一資源識別子

  • Uniform Resource Locator (統一 資源 位置指定子)
    • 場所を示す書き方のルール
  • UniformResourceName (統一資源名)
    • 名前を永続的に識別する書き方のルール

がある。この2つはいずれもURI。つまり「アドレス可能である」というのは、統一資源識別子によって、一意になり、Web上に存在するデータを、簡単に示すことができる、ということ。

1-6. HTTPメソッド(GET・POST・PUT・DELETE)

クライアントが自分の意図をサーバーにどのように伝えるか?

サーバーは、特定のリクエストが何らかのデータを取得するためのリクエストであって、そのデータを削除したり別のデータで上書きしたりするためのリクエストではないことをどのようにして知るのだろうか。

データの操作に関する情報をメソッド情報と呼ぶ。Webサービスでメソッド情報を伝える方法 の1つは、それをHTTPメソッドに含めることです。 HTTPメソッド名の大きな利点は、標準化されているため世界中で使用できることです。 クライアントとリソース間のすべてのやり取りは、いくつかの基本的な HTTPメソッドによって処理される。どのリソースもこれらのメソッドの一部またはすべてをサポートし、メソッドはそれらをサポートするどのリソースでも同じように機能します。

引用元:Web APIの設計

1-6-1. GET 『リソースの取得』

「何らかのデータを取得する」

GET リクエストは、指定したURIの情報を取得するメソッド。リソースに関する情報をリクエストする。情報は、一連のヘッダーと表現として送信される。 クライアントがGETリクエストとともに表現を送信することはありません。

リソースを識別できる場合は、レスポンスコード200 (OK)と表現を送信します。 条件付きのGETを必ずサポートする。

利用頻度はおそらく最も高く、Webページ、画像、映像、フィードの取得などがこれに当たります。

1-6-2. POST 『リソースの作成、追加』

GETに次いで利用頻度が高い

POST リクエストは、既存のリソースから新しいリソースを作成する試みです。 ツリーのルートがそのすべてのリーフノードの親であるのと同様に、既存のリソースはデータ構造の意味において、新しいリソースの親になることができます。

POST リクエストとともに送信される表現は、新しいリソースの初期状態を説明する。PUT リクエストの場合と同様、 POST リクエストに表現を含める必要はない。POST リクエストは、まったく新しいリソースを作成せずに、既存のリソースの状態に追加するために使用することもできる。

  • 子リソースの作成(表現を解析し、適切な URI を選択し、そこに新しいリソースを作成する)

    • POSTの代表的な機能で、あるリソースに対する子リソースを作成することができる。ブログ記事の投稿などで使われる。
  • リソースへの状態の追加

    • 子リソース作成ほどメインで使わないが、既存リソースへの状態の追加もできる。
  • ほかのメソッドでは対応できない処理(オーバーロードPOST)

    • POSTの3つ目の機能は、ほかのメソッドでは対応できない処理の実行。例として、検索結果を表示するURIが挙げられる。http://example.jp/search?q={検索キーワード} 通常はこのURIをGETできるが、検索キーワードがとてもながい場合、URIにキーワードを入れてGETする方式は使えない。これはURIを実装する上で、2000文字の制限があるため。

      こういうときにPOSTを使う。GETがキーワードをURIに含めるのに対して、POSTはリクエストボディに入れることができる。そのため、どんなにながいキーワードにも対応できます。

リクエストが成功した場合、レスポンスコード 201(Created) を送信し、新しいリソースのURIをLocation ヘッダーに設定する。 リソースを作成するための十分な情報が提供されていない場合は、レスポンスコード400 (Bad Request) を送信する。提供されたリソースの状態が既存のリソースと競合する場合は、レスポンスコード 409 (Conflict) を送信し、問題のリソースをポイントする Location ヘッダーを追加する。リソースに追加するための POST 表現を解析する。 表現が意味をなさない場合は、レスポンスコード400 (Bad Request) を送信する。それ以外の場合は、表現の情報を取り込むためにリソース状態を変更する。 レスポンスコード200 (OK) を送信する。

1-6-3. PUT 『リソースの更新、作成』

「別のデータで上書きする」

PUT リクエストは、リソースの状態に関するクライアントの提案です。クライアントは通常、PUT リクエストとともに表現を送信し、サーバーはリソースの状態が表現の内容と一致するように、作成や変更を試みる。 表現を伴わない PUT リクエストは、単にリソースが特定のURI に存在することのアサーション(表明)です。

  • リソースの更新 新しい内容となる表現をPUTリクエスト共に送信し、既存のリソースの表現を上書きします。

  • リソースの作成 POSTでもできるリソースの作成がPUTでもできる。例えば http://example.jp/newitem がまだ存在しないとする。このとき、PUTは存在しないURIへのリクエストとなるため、サーバは新しくリソースを作成すると解釈する。そして、リクエストが成功すると[201 Created]を返す。 新しいリソースを作成する場合は、表現を解析し、それに基づいてリソースの初期状態を構成します。/newitem が存在していた場合は、ただの上書き処理になります。

どのリソースにも該当しない URI への PUT リクエストには、ステータスコード 404 (Not Found) を返すか、 その URIにリソースを作成します。

リソースがすでに存在する場合は、表現を解析し、このリソースの状態に対する一連の変更する。変更によってリソースが不完全な状態または矛盾した状態になる場合、リソースを新規作成するための十分な情報がない場合は、レスポンスコード400 (Bad Request) を送信する。

変更によってリソース状態がほかのリソースと競合する場合は、レスポンスコード 409 (Conflict)を送信する。リソース状態を変更することにより、リソースを別のURI で利用できるようになる場合は、レスポンスコード 301 (MovedPermanently) を送信し、 新しいURI を Location ヘッダーに設定する。 それ以外の場合は、レスポンスコード200 (OK) を送信する。 URI を変更した場合、 古い URI へのリクエストには、レスポンスコード 301 (Moved Permanently), 404 (Not Found)、 または 410(Gone) のいずれかを返すべきです。

1-6-4. DELETE 『リソースの削除』

「そのデータを削除する」

DELETE リクエストは、リソースがもはや存在すべきではないことを示すクライアントの提案です。クライアントが DELETE リクエストとともに表現を送信することはありません。レスポンスコード200 (OK) を送信する。

1-7. TCP / IPとは

HTTP は TCP/IP をベース。 TCP (Transmission ControlProtocol)とIP (Internet Protocol)は、インターネットの基盤を構成する重要なネットワークプロトコル

階層型プロトコル

名称 規格(プロトコル 主な利用例 コンピュータ上の処理
4層 アプリケーション層 HTTP,HTTPS,SMTP,POP3,
IMAP4,DHCP,DNS
SSH,SMTP など
Webサイト閲覧、メール、ファイル転送、名前解決 など 通信アプリケーションプログラム
3層 トランスポート層 TCP,UDP,NetWare/IP など TCP/UDPで通信方法選択
(データを適切なアプリケーションへ振り分け)
OS
2層 インターネット層 IP,ARP,RARP,ICMPなど ルーティング、エンドツーエンド通信
IPv4IPv6 で接続
OS
1層 ネットワーク
インターフェイス
Ethernet LAN
MACアドレスEthernetなどの
物理的なケーブルなどの通信方法
バイス、ドライバ、NIC

1-7-1. 階層型プロトコル

インターネットのネットワークプロトコルは階層型で1層ごとに抽象化して実装すれば、物理的なケーブルがメタルなのか光なのかといった下位層の具体的なことに左右されることなく、上位層を実装できます。

1-7-2. ネットワークインタフェース層

同一のネットワーク内でデータを転送する 一番下のネットワークインタフェース層は、物理的なケーブルやネット ワークアダプタに相当する部分です。

1-7-3. インターネット層

複数のネットワーク間のデータ転送を行う 多数のネットワーク同士を接続してデータ転送を行っているのはルータに相当する部分です。

この層が担当するのは、ネットワークでデータを実際にやりとりする部分 です。 TCP/IP ではIPが相当します。IPではデータの基本的な通信単位を「パケット」 (Packet) と呼びます。 指定したIPアドレスを送り先として、パケット単位でデータをやりとりしてIでは、自分のネットワークインタフェースでデータを送りだすことだけを保証しています。 送り出したデータが、多数のルータを経由して最終的な送り先まで届くかどうかは保証しません。

1-7-4. トランスポート層

データを適切なアプリケーションに振り分ける 最下層からトランスポート層まで正しく機能すると、送信元と宛先のアプリケーション間でデータの送受信ができるようになります。主なプロトコルTCPUDPに分けられます。

TCPは送信中にデータが破損してしまったり損失してしまっても、これらを検出してデータの再送を行い確実に通信をしてくれます。

IPが保証しなかったデータの転送を保証します。接続先の相手に対してコネクションを張り、データの抜け漏れをチェックし、データの到達を保証する仕組みです。例を上げるとWebサイトのWebページを閲覧したりメールの送受信を行うなどインターネットで実行する通信方法の殆どがTCPを利用しています。

TCPで接続したコネクションで転送するデータが、どのアプリケーションに渡るかを決定するのがポート番号です。ポート番号は1~65535の数値です。サーバ側のよく使われるポート番号にはデフォルトの番号が割り当てられており、 HTTPはデフォルトで80番ポートを使用します。

UDPは身近な機能を用いて相手にデータを送信する方法です。正確性は無いのですが、素早くデータを送信する際に適した方法です。例を上げると、Web会議や動画サイトの映像と音声の通信方法で、リアルタイムに通信をする方法です。従ってデータ通信にエラーが生じた際は、繰り返し再生するのではなく、映像の乱れや音声が途切れたりすることが生じ、リアルタイムに映像と音声が流れる仕組みです。

TCP UDP
通信方法 コネクション型 データダイヤグラム
特徴 確実性重視 即時性重視
信頼性 髙い 低い
利用速度 低速 高速
利用例 Webサイト閲覧、メールなど
一般的にインターネットを利用する方法
IP電話、映像配信、Web会議など
リアルタイム性を重視する方法

1-7-5. アプリケーション層

アプリケーションで扱うデータのフォーマットや手順を決める アプリケーション層は具体的なインターネットアプリケーション、たとえばメールやDNS、そしてHTTPを実現する層です。TCPでプログラムを作るときは、ソケット (Socket) と呼ばれるライブラリを使うのが一般的です。 ソケットはネットワークでのデータのやりとりを抽象化したAPIで、 送信、受信切断などの基本的な機能を備えています。 HTTPサーバやブラウザはソケットを用いて実装します。アプリケーションは基本的には人間が扱うため、文字や画像など人間が認識できるようにデータを表現します。主なプロトコルは「HTTP」「SMTP」「POP3」「IMAP4」「DHCP」「DNS」など

HTTPはWebブラウザで利用し、SMTPPOP3は電子メールソフトで利用します。DHCPDNSはアプリケーション通信を行うための準備のプロトコルとして補うことを担います。ほとんどのプログラミング言語にはHTTP を実装したライブラリが標準で付いているため、ソケットを使って HTTPを独自に実装することはほとんどないようです。しかしWebサービスやWeb APIを開発するにあたっては、フレームワークの細かな挙動や設定パラメータなどがプロトコルレベルでどのように動作するかを把握しておく必要がある。

2. HTTP のレスポンスステータスコードとは?

HTTP のレスポンスステータスコードは、特定の HTTP リクエストが正常に完了したどうかを示します。 サーバからのレスポンスの意味を表す3桁の数字コード。レスポンスは 5 つのクラスに分類されています。

  1. 情報レスポンス (100–199)
  2. 成功レスポンス (200–299)
  3. リダイレクトメッセージ (300–399)
  4. クライアントエラーレスポンス (400–499)
  5. サーバーエラーレスポンス (500–599)

2-1. HTTPレスポンスは大きく分けて三種類

  1. HTTPレスポンスコード
  2. レスポンスヘッダ
  3. ボディ
curl -I https://twitter.com/yoshitaro_yoyo

HTTP/2 200 
date: Thu, 27 Oct 2022 15:01:10 GMT
perf: 7626143928
expiry: Tue, 31 Mar 1981 05:00:00 GMT
pragma: no-cache
server: tsa_m
set-cookie: guest_id_marketing=v1%3A166688287077136753; Max-Age=63072000; Expires=Sat, 26 Oct 2024 15:01:10 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
set-cookie: guest_id_ads=v1%3A166688287077136753; Max-Age=63072000; Expires=Sat, 26 Oct 2024 15:01:10 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
set-cookie: personalization_id="v1_ihdlBnYARwM8D3YgWju5ow=="; Max-Age=63072000; Expires=Sat, 26 Oct 2024 15:01:10 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
set-cookie: guest_id=v1%3A166688287077136753; Max-Age=63072000; Expires=Sat, 26 Oct 2024 15:01:10 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
content-type: text/html; charset=utf-8
x-powered-by: Express
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
last-modified: Thu, 27 Oct 2022 15:01:10 GMT
x-frame-options: DENY
x-transaction-id: 9101702a5e93556d
x-xss-protection: 0
x-content-type-options: nosniff
content-security-policy: connect-src 'self' blob: https://*.pscp.tv https://*.video.pscp.tv https://*.twimg.com https://api.twitter.com https://api-stream.twitter.com https://ads-api.twitter.com https://aa.twitter.com https://caps.twitter.com https://pay.twitter.com https://sentry.io https://ton.twitter.com https://twitter.com https://upload.twitter.com https://www.google-analytics.com https://accounts.google.com/gsi/status https://accounts.google.com/gsi/log https://app.link https://api2.branch.io https://bnc.lt wss://*.pscp.tv https://vmap.snappytv.com https://vmapstage.snappytv.com https://vmaprel.snappytv.com https://vmap.grabyo.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net https://media.riffsy.com https://*.giphy.com https://media.tenor.com https://c.tenor.com ; default-src 'self'; form-action 'self' https://twitter.com https://*.twitter.com; font-src 'self' https://*.twimg.com; frame-src 'self' https://twitter.com https://mobile.twitter.com https://pay.twitter.com https://cards-frame.twitter.com https://accounts.google.com/ https://client-api.arkoselabs.com/ https://iframe.arkoselabs.com/  https://recaptcha.net/recaptcha/ https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/; img-src 'self' blob: data: https://*.cdn.twitter.com https://ton.twitter.com https://*.twimg.com https://analytics.twitter.com https://cm.g.doubleclick.net https://www.google-analytics.com https://maps.googleapis.com https://www.periscope.tv https://www.pscp.tv https://media.riffsy.com https://*.giphy.com https://media.tenor.com https://c.tenor.com https://*.pscp.tv https://*.periscope.tv https://prod-periscope-profile.s3-us-west-2.amazonaws.com https://platform-lookaside.fbsbx.com https://scontent.xx.fbcdn.net https://scontent-sea1-1.xx.fbcdn.net https://*.googleusercontent.com https://imgix.revue.co; manifest-src 'self'; media-src 'self' blob: https://twitter.com https://*.twimg.com https://*.vine.co https://*.pscp.tv https://*.video.pscp.tv https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net; object-src 'none'; script-src 'self' 'unsafe-inline' https://*.twimg.com https://recaptcha.net/recaptcha/ https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://client-api.arkoselabs.com/ https://www.google-analytics.com https://twitter.com https://app.link https://accounts.google.com/gsi/client https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js  'nonce-ZmQ3NmJlMzEtNTU3ZS00OTI0LTkwMDgtNjQ1N2RjZmI1Y2Zi'; style-src 'self' 'unsafe-inline' https://accounts.google.com/gsi/style https://*.twimg.com; worker-src 'self' blob:; report-uri https://twitter.com/i/csp_report?a=O5RXE%3D%3D%3D&ro=false
strict-transport-security: max-age=631138519
cross-origin-opener-policy: same-origin-allow-popups
cross-origin-embedder-policy: unsafe-none
x-response-time: 183
x-connection-hash: 7d904b5ae825c89eec55789dc9aab3357cc5950ed814a07b1b04ea7047ec3e8a

2-1-1. HTTPレスポンスコード

レスポンスメッセージの1行目は「ステータスライン」 (Status Line) と呼び、プロトコルバージョン (HTTP/2)、ステータスコード (200)、 テキストフレーズ (OK)から成ります。

HTTP/2 200 OK

ステータスコードはリクエストの結果をプログラムで処理可能な数値コードで表現します。「200」はリクエストが成功したことを示します。

2-1-2. レスポンスヘッダ

レスポンスメッセージの2行目以降はヘッダです。 Content-Type ヘッダで HTML の MIME(Multipurpose Internet Mail Extensions) メディアタイプ (text/html)とその文字エンコーディング方式 (utf-8) を指定しています。

Content-Type: text/html; charset=UTF-8

2-1-3. ボディ

ヘッダ以降のボディには HTML が含まれています。 Webブラウザにドキュメントの処理方法を指示するためので、表現とも呼ばれる。実際に本文が含まれている。 ボディは、GET リクエストの結果である。

レスポンスヘッダー Content-Type は、ボディのメディアタイプを示す。 例えばメディアタイブが text/html の場合。Webブラウザはボディを HTML ドキュメント (Webページ)としてレンダリングできることを認識する。 最も一般的なメディアタイプは、テキストドキュメント (text/html)、構造化データドキュメント (application/xml)、およびイメージ(image/jpeg) を示す。 REST や HTTPに 関するほかの文献では、メディアタイプを「MIMEタイプ」、「コンテンツタイプ」、または 「データタイプ」と呼ぶことがある。

以降はレスポンスコードと関連するヘッダーについて、網羅的にまとめて記述していこうと思います。以下のソースとして再構成して記述します。

3. HTTPレスポンスコード概要

クライアントに問題を知らせるためのサーバーの試み。レスポンスコードはドキュメントやメタデータの一部ではないので、クライアントはレスポンスの最初の1行を見るだけで、エラーが発生したかどうかを知ることができる。

公式の HTTPレスポンスコードは41個、日常的に使用する上で重要なのは、そのうち10個程度とのこと。古い書籍を参考にしているため現状とは異なる可能性もあるかもしれませんが、技術的に普遍的な部分なので大きく変わってはいないのではと考えています。

引用書籍:オライリー・ジャパン RESTful Webサービス

多くのWeb サービスはHTTPステータスコードを誤って使用している。 従来のWeb では、HTTPステータスコードをめったに使用しないからだ。
〜中略〜

コンピュータプログラムは、ドキュメントを見ただけでその正確な意味を突き止めることはできない。 同じドキュメントであっても、状況によっては、 それがエラーメッセージである場合と、 GET リクエストの妥当な結果である場合がある。 レスポンスをどちらと見なすのが正しいのかを合図する何らかの方法が必要だ。この情報をエンティティボディのドキュメントに追加するわけにはいかない。 そうすると、情報を取り出すためにドキュメントを理解する必要が生じてしまう。このため、プログラマブル Webでは、 HTTP のレスポンスコードが非常に重要となる。 レスポンスコードは、エンティティボディに含まれたドキュメントの処理方法か、 ドキュメントを理解できない場合の対処方法をクライアントに伝える。
〜中略〜

クライアント、またはファイアウォールといったクライアントとサーバー間の仲介者は、レスポンスの最初の3バイトを見ただけで、 HTTPリクエストの状態を理解することができる。
〜中略〜

問題は、公式の41個のレスポンスコードのほかに、 WebDAV などの規格によって定められたレスポンスコードが存在することだ。 レスポンスコードの多くはめったに使用されないし、しかもそのうち2つは決して使用されず、いくつかは重箱の隅をつつくような些細な点でしか区別されない。従来の Web に慣れている者(私たち全員)にとって、レスポンスコードの多様さには困惑させられる。

  • 使用すべき状況
  • 重要度
  • 関連するHTTPメソッド

以降は上記について記述していきたいと思います。ただ、あまりにも数が多いので重要度が比較的高いものを中心に記述したいと思いますが、まずは必要最低限な、言い換えれば最も重要なコードの紹介です。

3-1. 最低限必要な3~7個のコード

ステータスコードの数を少なく保ちたい場合は、ステータスコードを3つだけ提供すればよい。それらだけでも、クライアントがレスポンスを処理するために知っておく必要のある基本情報を伝えることができる。

❐ 200 (OK)

すべてが正常である。エンティティボディにドキュメントが含まれている場合、それは何 らかのリソースの表現である。

❐ 400 (Bad Request)

クライアント側に問題がある。エンティティボディにドキュメントが含まれている場合、それはエラーメッセージである。うまくいけば、クライアントがエラーメッセージを理解し、それに基づいて問題を解決することができる。

❐ 500 (Internal Server Error)

サーバー側に問題がある。エンティティボディにドキュメントが含まれている場合、それはエラーメッセージである。クライアントはサーバーの問題を解決できないため、メッセージはあまり意味がない。特に Web サービスでよく使用される、さらに4つのエラーコードがある。

❐ 301 (Moved Permanently)

クライアントがリソースのURIを変化させる何らかのアクションを起こしたときに送信される。また、クライアントが古い URI をリクエストした場合にも送信される。

❐ 404 (Not Found) および 410 (Gone)

リソースと一致しない URI をクライアントがリクエストしたときに送信される。404 は、クライアントが何を要求しているのかサーバーがわからない場合に使用される。410 は、以前 はそこにリソースがあったが、もはや存在しないことをサーバーが知っている場合に使用される。

❐ 409 (Conflict)

1つ以上のリソースが矛盾した状態になるような処理をクライアントが実行しようとしたときに送信される。

4. HTTPレスポンスコード詳細

ここからは、それぞれ100〜500台のレスポンスコードのについて紹介します。

4-1. 1xx:情報レスポンス(処理中)

1xx シリーズのレスポンスコードは、 HTTP サーバーとのネゴシエーションでのみ使用される。
「リクエストは受け取られた。処理は継続される。」

❐ 100 Continue 「継続」

重要度:中
関連HTTPメソッド:全て
ボデイ:なし
継続。クライアントはリクエストを継続できる。クライアントの最初のリクエストで省略された表現を含めて、最初のリクエストを再送すべきであることを示す。クライアントは、表現を送信しても結果的にそれが拒否されることについて心配する必要はない。

例として、クライアントがExpect: 100-continueヘッダをつけたリクエストを行い、リクエストヘッダを送りきった時点でサーバが100 Continue を返す。これにより無駄に巨大なリクエストを送信しなくて済むようになる。

まず、クライアントはExpectヘッダを付けてリクエストを送ります。

POST /files/bar.txt HTTP/1.1
Host: example.jp
Expect: 100-continue
Content-length: 524288000

◎ ヘッダー Expect

タイプ:リクエストヘッダー
重要度:中
値: 100-continue
このヘッダーで、クライアントがサーバーに /files/bar.txt というリソースをPOST(送信)していいかお尋ねする。なので、本当の送信ではない。このリクエストヘッダーに「100-continue」という文字列を設定することでお尋ねができる。

この場合、サーバは Content-length を調べ、500MBのファイル送信を受け入れるかどうか判断する。

可能な場合、クライアントが 「次の段階へ進み」、本当のリクエストを送信すべきである場合、 サーバーはレスポンスコード100(Continue) を送信。そこからクライアントは再びPOSTリクエストを送信し、 Expect は省略、ボディに500MBファイルが送信される。

許可できない場合、クライアントが次の段階へ進むべきではない場合、サーバーはレスポンスコード 417 (Expectation Failed) を送信する。
ファイルサイズが大きいか、/files/bar.txt にあるリソースが書き込み不可なのか、クライアントが提示した認証情報が不適切だったか。

4-2. 2xx:成功レスポンス

2xx シリーズのレスポンスコードは、処理が成功したことを示す。
「リクエストは受け取られ、理解され、受理された」

❐ 200 OK 「OK」

重要度: 非常に高い
関連HTTPメソッド:全て
ボディ: GET リクエストの場合は、クライアントがリクエストしたリソースの表現。ほかのメソッドでのリクエストの場合は、選択したリソースの現在の状態の表現、または実行したアクション説明や処理結果

ほとんどの場合、これはクライアントが望んでいるコードである。 クライアントがリクエストしたアクションがサーバー上で正常終了し、さらに具体的な2xxシリーズのコードでは適切でないことを示す。レスポンスとともに要求に応じた情報が返される。ブラウザでページが正しく表示された場合は、ほとんどがこのステータスコードを返している。

  • GET: リソースが読み込まれ、メッセージ本文で転送された。
  • HEAD: メッセージ本文がなく、表現ヘッダーがレスポンスに含まれている。
  • PUT または POST: 操作の結果を表すリソースがメッセージ本文で送信される。
  • TRACE: メッセージ本文に、サーバーが受け取ったリクエストメッセージが含まれている。

❐ 201 Created 「作成」

重要度: 高
関連HTTPメソッド:POST / PUT
レスポンスヘッダ: Location
ボディ: リクエストが成功し、新しいリソースを作成したことを示し、そのリソースにリンクする。Location ヘッダーを使用してリソースの実際の場所をクライアントに伝える場合は、そのリソースの表現を含むことができる。

サーバーは、クライアントのリクエストに応じて新しいリソースを作成する際に、このステータスコードを送信する。 リクエストが POST だった場合、Location ヘッダには新しいリソースの URI が絶対 URI で入る。

◎ ヘッダー Location

タイプ: レスポンスヘッダー
重要度: 非常に高い
値: 新しいリソースへの正当なURI が含まれる
リダイレクト時の移動先のURI、または新規作成時のURIを示す。

これは、多くの関連する機能を持つ多目的ヘッダーである。レスポンスコード 3xx (Redirection)と深く関連しており、 HTTP リダイレクトを取り巻く混乱の多くは、このヘッダーを解釈する方法に関係している。

このヘッダーは、通常、リソースへのアクセスに使用すべき URI をクライアントに伝える。おそらく、クライアントのリクエストによってリソースが作成された (レスポンスコード 201 (Created))、またはリソースの URI が変更された (301 (Moved Permanently)) ために、クライアントはそのURI をまだ知らない。あるいは、完全に正しくないものの、サーバーが間違いに気付かないほどわずかに異なる URI をクライアントが使用したことも考えられる。その場合のレスポンスコードは、同じく 301、307(TemporaryRedirect)、または 302 (Found) になる可能性がある。

Location の値が単にデフォルト URI の場合がある。たとえば、これは300 (Multiple Choices)など、あいまいなリクエストに対する多くの解決策の1つである。また、303 (See Other) など、Location の値が、クライアントがアクセスしようとしたリソースではく、補足情報を提供するほかのリソースをポイントすることもある。

このように、このヘッダーは特定の HTTPレスポンスコードとの関連でのみ意味をなす。

❐ 202 Accepted 「受理」

受理。リクエストは受理されたが、処理は完了していない。

重要度: 中 ボディ: クライアントがリクエストをあとから確認できない場合は、少なくともリクエストがいつ処理されるかの予測を示す
関連メソッド: 全て
レスポンスヘッダ: Location / Retry-After

処理結果が得られるリソースへのリンクや予測処理時間すべてクライアントからのリクエストは受け入れられたものの、サーバ側でリアルタイムに処理できない、または処理しないことを示す。これはあいまいです。 HTTP ではリクエストを処理した結果を示す非同期なレスポンスを後から送信する方法がないためです。典型的には、POST や PUT でリソースを作成・更新したときに、その処理に非常に時間がかかりそうな場合に返します。

リクエストが非同期のアクション、 実世界でのアクション、 またはクライアントを待たせておいても意味がないほど時間がかかるアクションを引き起こす場合の適切なレスポンスで非同期処理に対する RESTful システムの重要な部分。バッチ処理向け。

クライアントがあとから確認できるように、未処理のリクエストをリソースとして提供すべきである。Location ヘッダーには、このリソースへの URI を設定することができる。

◎ ヘッダー Retry-After

タイプ:レスポンスヘッダー
重要度:低~中
関連HTTPメソッド: GET
値: 日時、または数値(秒)

このヘッダーの値は、クライアントが再試行すべき時間、または待機すべき秒数を示す。

通常、このヘッダーは、エラーを示すレスポンスコードである 413 (Request Entity Too Large)、 または5xxシリーズ(サーバー側のエラー)の1つに付随する。このヘッダーは、サーバーがリクエストを直ちに処理することはできなかったが、同じリクエストをあとから処理できる可能性があることを示す。

サーバーがすべてのクライアントに対して同じルールで Retry After 値を選択した場合、それは単に、同じクライアントが同じリクエストを同じ順序で少し後に送信することを保証するだけであり、おそらく問題が繰り返されるだけである。サーバーは、Ethernet のバックオフ期間と同様 に、何らかのランダム手法を用いて Retry After の値を変化させる必要がある。

❐ 204 No Content 「内容なし」

重要度: 高い
関連HTTPメソッド: POST / PUT / DELETE
ボデイ: なし

内容なし。リクエストが成功したものの、クライアントに返すコンテンツがないことを示します。

このステータスコードは、通常、サーバーがステータスメッセージまたは表現の返送を拒否した場合に、PUT POST DELETE リクエストに対して送信される。サーバーは、GET リクエストに関連して204を送信することもあり、リクエストされたリソースは存在するが、それが空の表現であることを示す。

POSTメソッドでフォームの内容を送信したが、ウェブブラウザの画面を更新しない場合や DELETE へのレスポンス、 Ajax アプリケーションでよく使用される。サーバーはこのステータスコードを使用し、入力は受理されたが、クライアントがUIエレメントを変更すべきではないことを伝える。

❐ 206 Partial Content 「部分的内容」

重要度: 部分 GET をサポートするサービスにとっては非常に高く、それ以外は低い
関連HTTPメソッド: GET
ボデイ: 部分GET リクエストの場合は、クライアントがリクエストした指定された範囲のリソースの表現。 ほかのリクエストの場合は、選択したリソースの現在の状態の表現、 または実行したアクションの 説明。
リクエストヘッダ: Range、 If-Range
レスポンスヘッダ: Content-Range

200 (OK) と同じだが、Content-Range リクエストヘッダーを使用するリクエストへのレスポンスを表す。クライアントは通常、部分GETリクエストを送信して、大きなバイナリ表現の中断されたダウンロードを再開する。

GETの際に Range ヘッダでリソースの範囲をバイトで指定すると、リソースの一部だけを取得できます。これを「部分的GET」 (Partial GET) と呼びます。このステータスコードは部分的 GET が成功したことを示します。 レスポンスの Content-Range ヘッダには Range ヘッダで指定した部分が入ります。

ダウンロードツール等で分割ダウンロードを行った場合や、レジュームを行った場合に返される。

条件付きの部分 GET はそれほど頻繁に使用されない。なぜなら、クライアントが大きな表現から数バイトを取得した後、 あとから同じバイトを取得することはまれだからである。

◎ Rangeヘッダー

タイプ: リクエストヘッダー
重要度: 中
関連HTTPメソッド: GET
値: 取得したい部分

このヘッダーは、クライアントがリソースの表現の一部のみをリクエストしようとすることを示す。取得したい幅をバイトで指定する。

クライアントがこのヘッダーを送信するのは、通常、以前に大きな表現のダウンロードを試み、途中で切断されたためである。ここで、表現の残りを取得するために再びリクエストする。表現が前回の リクエスト以降に変化している場合は、最初から GET を実行する必要があるだろう。

◎ ヘッダー Content-Range

タイプ: レスポンスヘッダー
重要度: 中〜高
関連HTTPメソッド: GET
値: バイト幅

このレスポンスヘッダーは、クライアントが Range リクエストヘッダーを使用して部分的な GET リクエストを送信する際に、クライアントが表現のどの部分を取得しようとしているかを示す。

4-3. 3xx:リダイレクトメッセージ

3xxステータスコードは、クライアントが要求しているものを取得するには、 さらに作業が必要 であることを示す
リクエストを完了させるために、追加的な処理が必要

リダイレクトは GET リクエストで最もよく使用され、通常は、ほかの URI に対する2つ目のGETリクエストを送信しなければ、クライアントが望んでいる表現を取得できないことを示す。この2つ目のURIは、Location レスポンスヘッダーで送信される。

301 (Moved Permanently)、 302 (Found) 303 (See Others)、 および 307 (Temporary Redirect) はどれもよく似ているため、これらは最も注意が必要なレスポンスコードである。多くのアプリケーションでは、クライアントをある URI から別の URI へ移動させるための手段として、これらのステータスコードを見境なく使用し、元のリソースの観点からの意味を軽視している。

❐ 301 Moved Permanently 「恒久的に移動した」

重要度: 中
関連HTTPメソッド: 全て
ボデイ: 移動先のURIへのリンクを含んだHTMLなど
リクエストヘッダ: サーバーは Location に正当な URI を追加すべきである

サーバーは、クライアントがどのリソースにアクセスしようとしているかを知っているが、リクエストに使用された URI はそのリソースを処理しない。クライアントが新しいURIに気付き、今後のリクエストでそれを使用することを要求する。

リクエストしたリソースが新しいURIに恒久的に移動されているときに返され、Location:ヘッダに移動先のURLが示されている。

サーバーは、クライアントがどのリソースにアクセスしようとしているかを知っているが、リクエストに使用された URI はそのリソースを処理しない。クライアントが新しいURIに気付き、今後のリクエストでそれを使用することを要求する。

ウェブサイトが移転した場合などに用いる。HTTPからHTTPSへの移転も該当する。そのほか、ファイルではなくディレクトリに対応するURLの末尾に/を書かずにアクセスした場合に返される。このステータスコードを使用して、URI が変化したときに、古い URI が無効になるのを防ぐことができる。

❐ 302 Found 「発見」

重要度: クライアントを作成している場合は特に、このステータスコードを知っていることが非常に重要となる。しかしこのステータスコードを使用することはお勧めしない。
関連HTTPメソッド: POST
ボデイ: 移動先のURIへのリンクを含んだHTMLなど
リクエストヘッダ: サーバーは Location に正当な URI を追加すべきである

このステータスコードは、リダイレクト関連のほとんどの混乱の根本的な原因である。

本来はリクエストしたリソースが一時的にそのURLに存在せず、クライアントは Location ヘッダが示す別のURIに、メソッドを変えずにリクエストを再送信する必要があることを示すステータスコード

しかし、例えば掲示板やWikiなどで投稿後にウェブブラウザに対して他のURLに転送させたいときにもこのコードが使用されるようになったため、302はFoundになり、本来の 302 の意味のステータスコードは 307 Temporary Redirected として再定義されたので、 現在はこのステータスコードを利用 することは推奨されていません。

その違いは、PUT POST, または DELETE リクエストへ のレスポンスとして302を受け取ったときに、クライアントが何を実行すべきかによって決まる。

このあいまいさを解消するために、HTTP 1.1 では、このレスポンスコードの名前が「Found」に 変更され、レスポンスコード307が作成された。このレスポンスコードは現在も広く使用されているが、あいまいなので、サービスでは307の代わりに303を送信することが推奨される。ただし、303 または 307 を理解しない HTTP 1.0 クライアントとやり取りしている場合は別である。

❐ 303 See Other 「他を参照せよ」

重要度: 高
関連HTTPメソッド: POST
ボデイ: 移動先のURIへのリンクを含んだHTMLなど
リクエストヘッダ: サーバーは Location に正当な URI を追加すべきである

リクエストに対するレスポンスが他のURLに存在するときに返される。リクエストに対する処理結果が Location ヘッダで示されるURIからGET で取得できることを示します。リクエストしたリソースは確かにそのURLにあるが、他のリソースをもってレスポンスとするような場合に使用する。302の説明で挙げたような、掲示板やWikiなどで投稿後にウェブブラウザに対して他のURLに転送させたいときに使われるべきコードとして導入された。

ステータスコード 303は、リソースを正規化するためのよい方法である。 リソースは多くのURI を通じて提供することができるが、表現につき「本当」のURIは1つしか存在しない。その他の URI はすべて、303 を使用してその表現の正当なURIをポイントする。

❐ 304 Not Modified 「未更新」

重要度: 高
関連HTTPメソッド: GET
ボデイ: なし
レスポンスヘッダ:Date ETag content-Location
キャッシュヘッダ:Expires、Cache-Control、Vary

これはキャッシュ用に使用します。このレスポンスコードはクライアントに対して、レスポンスは変更されていないことを示します。よって、クライアントはキャッシュ済みのレスポンスを使い続けます。

クライアントが日曜日の日付で If-Modified-Since ヘッダを使用したリクエストを行い、表現が日曜日以降に変更されていない場合は、304が適している。 200 (OK) も適しているが、表現を再び送信すると、帯域幅を無駄にすることになる。クライアントはその表現をすでに持っているから。

◎ ヘッダー Date

タイプ: リクエストおよびレスポンスヘッダー
重要度: リクエストに対しては高く、レスポンスに対しては必須
値: 日時

リクエストヘッダーとしては、リクエストが送信された時間をクライアント時間で表す。レスポンスヘッダーとしては、リクエストが完了した時間をサーバー時間で表す。レスポンスヘッダーとしての Date は、キャッシュによって使用される。

◎ ヘッダー ETag

タイプ:レスポンスヘッダー
重要度: 非常に高い
値: Etag を示す文字列

リソースが更新されたら変化する値。

ETag の値は、表現の特定のバージョンを示す不透明な文字列である。 表現が変化すると、 ETagも変化する。GET リクエストへのレスポンスは、可能な限り、このヘッダーで送信することになっている。 クライアントは、その後の条件付きGETリクエストで、ETag ヘッダーの値を IfNone Match の値として使用することができる。

表現が変化していなければ、ETag も変化していないので、ここでは複数の言語を指定することができる。

◎ ヘッダー Cache-Control

タイプ: リクエストおよびレスポンスヘッダー
重要度: 中
値: 識別子 no-cache, max-age など

クライアントとサーバーが従うべきキャッシュ方法を示す。

このヘッダーには、クライアントとサーバー間の任意のキャッシュへのディレクティブが含まれ (クライアントまたはサーバー上のキャッシュも含む)。 データをキャッシュする方法と、それを 削除する時期を細かく規定する。

◎ ヘッダー Expires

タイプ: レスポンスヘッダー
重要度 : 中
値: 日時

このヘッダーは、クライアント、またはサーバーとクライアント間のプロキシに、 特定の時間までレスポンスをキャッシュできることを伝える。

❐ 307 Temporary Redirect 「一時的リダイレクト」

重要度: 高
関連HTTPメソッド: 全て
ボデイ: 移動先のURIへのリンクを含んだHTMLなど
レスポンスヘッダ: Location

リクエストしたURIが存在しなかったので、クライアントは Locationへッダが示す別のURIに、メソッドを変えずにリクエストを再送信する必要があることを示します。このステータスコードは 302 Found が本来持つべきだった意味を再定義し、正しく利用するように HTTP 1.1 で追加されました。302の規格外な使用法が横行したため、302の本来の使用法を改めて定義。しかし結局、このステータスコードを正しく実装しているブラウザはほとんどありません。

ユーザーエージェントは使用する HTTP メソッドを変更してはならない点が、302 Found と異なります。始めのリクエストで POST を用いた場合は、次のリクエストでも POST を使用しなければなりません。

GET リクエストの場合、リクエストされるものはサーバーが表現を送信するものだけなので、このステータスコードは 303 (See Other) とまったく同じである。GET リクエストへの適切なレスポ ンスが307である代表的なケースは、サーバーがクライアントをミラーサイトに誘導したい場合である。

しかし、 POST PUT DELETE リクエストの場合、サーバーがリクエストに応じて何ら かのアクションを起こすことを要求されるため、このステータスコードは303とは大きく異なる。 POST PUT DELETE リクエストへのレスポンスコード303 は、処理は正常終了したが、 レスポンスのエンティティボディがこのリクエストとともに送信されないことを意味する。 クライアントがレスポンスのエンティティボディを要求する場合は、別のURI に GET リクエストを送信する必要がある。

POST PUT DELETE リクエストへのレスポンスコード307 は、サーバーが処理を実行しよ うとすらしていないことを意味する。 クライアントは、Location ヘッダーに含まれている URI へ リクエスト全体を再送する必要がある。

記入欄の空いている処方箋を持って薬局へ行くとしよう。 303 は、処方箋に記入しました。次の窓口で薬を受け取ってください」と言う薬剤師である。307 は、「処方箋に記入できません。隣の薬局に行ってください」と言う薬剤師である。

❐ 308 Permanent Redirect 「恒久的リダイレクト」

重要度: 中
関連HTTPメソッド: 全て
ボデイ: 移動先のURIへのリンクを含んだHTMLなど
リクエストヘッダ: サーバーは Location に正当な URI を追加すべきである

リクエストしたリソースは恒久的に移動されているときに返される。Location:ヘッダに移動先のURLが示されている。 301の規格外な使用法が横行したため、301の本来の使用法を改めて定義したもの。

4-4. 4xx:クライアントエラーレスポンス

クライアント側で問題が起きていることを示す。 認証、表現の フォーマット、または HTTP ライブラリ自体に問題がある。クライアント側で問題を解決する必要がある。
クライアントエラークライアントからのリクエストに誤りがあった

❐ 400 Bad Request 「リクエストが不正である」

重要度: 高
関連HTTPメソッド: 全て
ボデイ: クライアント側に問題があるとサーバーが考える理由を説明する

リクエストの構文が間違えていることを示します。ほかの 4xxエラーコードが適さない場合にも使用され、クライアント側の汎用エラーステータスである。クライアントに未知の4xx系ステータスコードが返ってきた場合、400 Bad Requestと同じ扱いをするよう仕様で定められています。

クライアントが PUT または POST リクエストとともに表現を送信し、表現のフォーマットは正しいものの、意味をなさない場合によく使用される。

❐ 401 Unauthorized 「認証が必要である」

重要度: 高
関連HTTPメソッド: 全て
ボデイ: ユーザーが提供した場合) 認証情報が拒否された理由と、受理される認証情報を示す。 エンドユーザーがWebサイトに登録するか、「ユーザーアカウント」 リソースを作成することにより認証情報を取得できる場合は、登録用URIへのリンクがあると効果的である
リクエストヘッダ: Authorization
レスポンスヘッダ: WWW-Authenticate ヘッダーは、サーバーが受け入れる認証の種類を説明

クライアントが適切な認証情報を提供せずに保護されたリソースを操作しようとした。不正な認証情報を提供したか、認証情報を提供しなかった可能性がある。 認証情報は、ユーザー名とパスワード、APIキー、または認証トークンなど、当該のサービスが要求するものである。

クライアントがURIにリクエストを送信し、送信する認証情報の種類とそのフォーマットを知るために、 401を受け取ることがよくある。 実際、HTTP Digest モードの認証は、この振る舞いに依存する。

サーバーは、権限のないユーザーにリソースの存在を知られたくない場合、嘘をついて、401の代わりに 404 (Not Found) を送信することがある。この場合の欠点は、サーバーがそのリソースに対してどのような種類の認証を要求するかを クライアントが事前に知っている必要があることだ。HTTP Digest のような認証方式はうまくいかない。

◎ ヘッダー Authorization

タイプ: リクエストヘッダー
重要度: 非常に高い
値: 認証情報

このリクエストヘッダーには、合意に基づく方式に従ってクライアントがエンコードした、ユーザー名とパスワードなどの認証情報が含まれる。サーバーは、認証情報をデコードして、 リクエストを処理するかどうかを決定する。理論上、このヘッダーは拡張可能なので、誰もが絶対に必要とする唯一の認証ヘッダーである

最も一般的な方式は HTTP Digest だが、クライアントとサーバーが理解する方式であれば、何でもかまわない。実際、 HTTP 自体も、Authorization の上で動作する X-WSSEのような非公式のリクエストヘッダーで拡張されてい る。

◎ ヘッダー WWW-Authenticate

タイプ: レスポンスヘッダー
重要度: 重要度: 非常に高い
値: 認証方式

このヘッダーは、レスポンスコード 401 (Unauthorized) に付随する。次回クライアントがそのURIにリクエストを送信するときに、サーバーが認証情報の送信を要求することを示す。また、サーバーが想定している認証の種類も示す。認証の種類には、 HTTP Basic 認証、 HTTP Digest 認証 または WSSEのような非標準の認証がある。

❐ 403 Forbidden 「禁止されている」

重要度: 中
関連HTTPメソッド: 全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント

401 Unauthorized はクライアントが適切な認証情報を提示しなかったこ とを示しますが、403 Forbidden はそれ以外の理由でリソースを操作できないことを示します。クライアントのリクエストのフォーマットは正しいが、サーバーがそれを処理しようとしない。401 Unauthorized とは異なり、クライアントの ID がサーバーに知られています。

アクセス権がない場合や、ホストがアクセス禁止処分を受けた場合などに返される。社内(イントラネット)からのみアクセスできるページに社外からアクセスしようとした。特定の時間帯しか、あるいは特定のIPアドレスからしかアクセスできないリソースであることを示す

ただし、 403 Forbidden を返すとそのリソースが存在することはクライアントに明らかになってしまいます。 リソースの存在自体を隠したいときは 404 Not Found を使うこともできます。

クライアントのリクエストが整形式である場合、このステータスコードが5xxシリーズ(サーバー 側のエラー)ではなく 4xxシリーズ(クライアント側のエラー) に含まれているのはなぜか。それは サーバーがリクエストの形式ではなく、リクエストが送信された日時など、 リクエストのそのに基づいて決断を下すからである。

404 Not Found 「未検出」

重要度: 高
関連HTTPメソッド: 全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント

おそらく最もよく知られている HTTPステータスコード。404 は、サーバーがクライアン URIをリソースにマッピングできないことを示す。

もう少し役に立つ410 (Gone) と比べてみよう。Web サービスは、URIが「空いている」ことをクライアントに知らせるために、レスポンスコード 404 を使用することができる。その場合、クライアントはそのURI への PUT リクエストを送信して、新しいリソースを作成することができる。

404 は、403 または 401 を隠すための嘘であるかもしれないことに注意しよう。リソースは存在するが、サーバーがそのことをクライアントに教えたくないのかもしれない。API では、これは通信先が有効であるものの、リソース自体が存在しないことを意味することがあります。

❐ 405 Method Not Allowed 「許可されていないメソッド」

重要度: 中
関連HTTPメソッド: 全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント
レスポンスヘッダ: Allow

POSTメソッドの使用が許されていない場所で、POSTメソッドを使用した場合に返される。

クライアントが、このリソースがサポートしないHTTPメソッドを使用しようとした。たとえば、読み取り専用のリソースは、 GET と HEAD しかサポートしない可能性がある。 別のリソースは、GET と POST をサポートするが、PUT と DELETE をサポートしない可能性がある。

レスポンスには Allowヘッダが含まれ、このURIがサポートしているメソッドの一覧が示されます。

Allow: GET, POST

このステータスコードは、たとえばAtomPubのコレクションリソースに PUT や DELETEを送った場合に返されるはずです。

◎ ヘッダー Allow

タイプ: レスポンスヘッダー
重要度: 重要度 現在は低いが、高くなる可能性がある
関連HTTPメソッド:
値:

このヘッダーは、 OPTIONS リクエストへのレスポンスで送信され、特定のURI がサポートしている統一インターフェイスのサブセットをクライアントに伝える。OPTIONS が使用されるようになれば、このヘッダーの重要性ははるかに高くなるだろう。

❐ 406 Not Acceptable 「受理できない」

重要度: 中
関連HTTPメソッド: 全て
ボデイ: 候補のURIのリスト
リクエストヘッダ: Accept, Accept-Charset, Accept-Language、 AcceptEncoding、Accept-Range

サーバーがこのレスポンスコードを送信する可能性があるのは、クライアントが表現として容認できるものに(おそらく Accept-*リクエストヘッダーを使用して)指定された制限が多すぎて、サーバーが表現を送信できない場合である。サーバーはクライアントの厳しい制限を無視し、単に優先度の高い表現をレスポンスコード 200 (OK) とともに送信することがある。従来の Web では、通常はそのように処理される。

例: サーバは英語か日本語しか受け付けられないが、リクエストのAccept-Language:ヘッダにzh(中国語)しか含まれていなかった。 例: サーバはapplication/pdfを送信したかったが、リクエストのAccept:ヘッダにapplication/pdfが含まれていなかった。 例: サーバはUTF-8の文章を送信したかったが、リクエストのAccept-Charset:ヘッダには、UTF-8が含まれていなかった。

◎ ヘッダー Accept

タイプ: リクエストヘッダー
重要度: 中
値: メディアタイプの優先度

クライアントは、サーバーにその表現で使用させたいデータフォーマットを伝えるために、Accept ヘッダーを送信する。クライアントによっては、JSON 表現を要求するものや、同じデー夕の RDF 表現を要求するものがある。 この情報を HTTPヘッダーに隠すことは、Web ブラウザにとっては好都合だが、Web サービスクライアントの唯一の解決策にすべきではない。

これは、HTML 表現の URI に「.html」を追加するといったがさつなルールを課すという意味ではない (Rails はそうしているが)。だが、筆者の考えるところでは、情報はどうにかして URI に含めるべきである。また、それに加えて Accept のサポートを考えているとしたら、それはとてもよいことである(これも Railsの流儀である)。

◎ ヘッダー Accept-Encoding

タイプ: リクエストヘッダー
重要度: 中~高
値: 圧縮方式の優先度

クライアントが理解できる圧縮方式を指定。クライアントはAccept-Encoding ヘッダーを送信して、レスポンスのエンティティボディを compress や gzip などのよく知られたアルゴリズムで圧縮することにより、 帯域幅を節約できることをサーバーに伝える。その名前にもかかわらず、このヘッダーは文字セットエンコーディングとは何の関係もない。

❐ 409 Conflict 「競合」

重要度: 高
関連HTTPメソッド: PUT / POST / DELETE
ボデイ: できればクライアントが競合を解決できるように、競合を説明するドキュメントを追加すべきである。
レスポンスヘッダ: Location

要求は現在のリソースと競合するので完了出来ない。

リクエストが要求したリソースに対する操作が、リソースの現在の状態と矛盾していることを示します。 たとえば空ではないディレクトリを削除しようとしたりした場合など、ほかのリソースと競合する状態であるときしようとしたり、リソースの名前をすでにほかで使われているものに利用します。

Amazon S3は、ユーザーが空ではないパケットを削除しようとすると、このレスポンスコードを送信する。

競合の原因が (ユーザー名をすでに使用されている名前に変更しようとするなど)ほかのリソースの存在にある場合、Location ヘッダーでそのリソースの URI つまり、競合の原因をポイントすべきである。

❐ 410 Gone 「消滅した」

重要度: 中
関連HTTPメソッド: 全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント

リソースは恒久的に移動・消滅した。どこに行ったかもわからない。 ただし、このコードは特別に設定しないと提示できないため、リソースが消滅しても404コードを出すサイトが多い。

このレスポンスコードは、 404 Not Found) と似ているが、もう少し情報を提供する。二度と復活せず転送先アドレスがない場合に送られます。リクエストされた URI が以前はリソースを参照していたが、そうではなくなったことをサーバーが知っている場合に使用される。サーバーはリソースの新しいURIを知らない。もし知っていれば、 301 (Permanent Redirect) を送信する。

永続的なリダイレクトと同様に、レスポンスコード410は、クライアントが現在のURIをその ボキャブラリから削除し、そのURIへのリクエストの送信を終了するという意味を持つ。永続的リダイレクトとは異なり、410は不適切なURIに代わるものを提供しない。単になくなるだけである。

RFC 2616 では、「期間限定のプロモーションサービス、およびサーバーのサイトでもはや活 動していない個人に属するリソースに対してレスポンスコード410の使用を提案している。

DELETE リクエストが正常終了したときに、このレスポンスコードを送信したいと考えるかもしれないが、それは少しわざとらしい。 クライアントには、リソースが削除されたのか、リクエストを送信する前からなかったのかはわからない。 DELETE リクエストの正常終了に対する正しいレスポンスは、 200 (OK) である。API はこのステータスコードの場合、削除されたリソースを無理に示そうとするべきではありません。

❐ 412 Precondition Failed 「前提条件で失敗した」

重要度: 中
関連HTTPメソッド: PUT / POST
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント
リクエストヘッダ: If-Match If-None-Match、 If-Unmodified-Since
レスポンスヘッダ: ETag Last-Modified

条件付きリクエストでクライアントが指定した事前条件が、サーバ側で合わないことを示します。 楽観的ロックで利用します。 例: リクエストのIf-Unmodified-Since:ヘッダに書いた時刻より後に更新があった場合に返される。

一般的な事前条件は、 If-Unmodified-Since である。クライアントはリソースを変更するためのリクエストを送信(PUT)するが、変更を実際に適用するのは、クライアントがそのリソースを最後に取得してから、ほかのクライアントによって変更されていない場合に限定する可能性がある 事前条件を指定しないと、クライアントがほかのクライアントによる変更を知らずに上書きしてしまったり、409 (Conflict) を引き起こしたりする可能性がある。

クライアントは、If-Match、If-None-Match、 If- Unmodified-Since のいずれかのヘッダーを使用して、このレスポンスコードを取得する場合がある。 If-None-Match は少し特別である。 クライアントが GET または HEAD リクエストを送信する際に If-None-Match を指定し、事前条件が満たされなかった場合、レスポンスコードは 412 ではなく 304 (Not Modified) である。これは条件付きの HTTP GET に基づいている。PUT POST DELETE リクエストで If-None-Match を指定し、事前条件が満たされなかった場合、レスポンスコードは 412 である。事前条件としてIf-Match または If -Unmodified-Since ヘッダーを使用する場合は、HTTPメソッドに関係なく、レスポンスコードは412である。

◎ ヘッダー If-Match

タイプ: リクエストヘッダー
重要度: 中
関連HTTPメソッド: PUT / DELETE
値: ETag

提示したETagと合致したらリクエストを実行することを示す。

このヘッダーは、ほかのヘッダーとの対比で説明するのが一番わかりやすい。 (この後で説明す る) If -Unmodified-Since と同様に、このヘッダーは条件付きGET 以外の HTTP アクションを 実行するために使用される。 しかし、 If - Unmodified-Since がその値として時間を取得するの に対し、このヘッダーはETag を値に持つ。 簡単に言うと、 If Unmodified-Since が If -Modified-Since と Last Modified に対するものであるように、このヘッダーは If-None-Match と ETag に対するものである。

◎ ヘッダー If-None-Match

タイプ: リクエストヘッダー
重要度: 非常に高い
関連HTTPメソッド: GET
値: ETag

提示したETagと合致しなかった時にリソースを取得することを示す。

このヘッダーも、 条件付き HTTP GET で使用される。 その値はETag レスポンスヘッダーの の値であり、このURIへの前回のリクエストから得られる。 前回のリクエストの後にETag が変化 している場合、 If -None-Match 条件が満たされ、サーバーが新しいエンティティボディを送信す る。 ETag が前回と同じであれば、条件は満たされず、サーバーはレスポンスコード 304 (Not Modified) を送信し、エンティティボディを送信しない。

◎ ヘッダー If-Modified-Since

タイプ: リクエストヘッダー
重要度: 非常に高い
関連HTTPメソッド: GET
値: 日時

提示した日時以降に流ソースが更新されていたらリソースを取得することを示す。

このリクエストヘッダーは、 条件付き HTTP GET の中心である。 その値は Last-Modified レ スポンスヘッダーの前の値であり、このURIへの前回のリクエストから得られる。 前回のリクエ ストの後にリソースが変化している場合、 新しい Last-Modifiedの日付はそれよりも新しい。 こ れは、 If-Modified-Since 条件が満たされ、 サーバーが新しいエンティティボディを送信する ことを意味する。 リソースが変化していない場合、 Last-Modified の日付はそのまま変わらず、 If Modified-Since 条件は満たされない。 サーバーはレスポンスコード304 (Not Modified) を送 信し、エンティティボディを送信しない。つまり、条件付き HTTP GET が成功するのは、この条件が満たされない場合である。 Last Modified の精度は1秒以内なので、条件付き HTTP GET が If-Modified-Since に のみ依存する場合、誤った結果を示すことがある。 ETag と If-None-Match も使用するのは、主 にそのためである。

◎ ヘッダー Last-Modified

タイプ: レスポンスヘッダー
重要度: 非常に高い
値: 日時

このヘッダーは、表現が最後に変更され た日時をクライアントに伝える。クライアントはこの日時を管理し、それ以降のリクエストのIf Modified-Since ヘッダーで使用することができる。

Web アプリケーションでは、通常、Last Modified は現在の時刻なので、条件付き HTTP GET は役立たない。Web サービスクライアントは、同じURIへのリクエストでサーバーを包囲攻撃にさらすことがよくあるので、 Web サービスはもう少しうまく対処すべきである。

❐ 415 Unsupported Media Type 「サポートしていないメディアタイプ」

重要度: 中
関連HTTPメソッド: PUT / POST
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント
リクエストヘッダ: Content-Type

クライアントが指定したメディアタイプをサーバがサポートしないこと を示します。たとえば画像登録 Web API などで、サーバがサポートする画 像形式はJPEGPNGだけなのにクライアントがGIF形式の画像を登録しようとしたとき、サーバーが XML を期待しているのに、クライアントが JSON を送信した場合などに用います。

メディアタイプは正しいものの、フォーマットが正しくないドキュメント(誤ったボキャブラリで書かれた XML ドキュメントなど)をクライアントが送信した場合は、より汎用的なレスポンスコード 400 (Bad Request)のほうが適している。

◎ ヘッダー Content-Type

タイプ: リクエストおよびレスポンスヘッダー
重要度: 非常に高い
値: メディアタイプ

間違いなく、最も有名なレスポンスヘッダーである。このヘッダーは、エンティティボディの種類をクライアントに伝える。従来の Web では Web ブラウザがこのヘッダーを使用して、エンティティボディをインラインで表示できるかどうか、そしてインラインで表示できない場合に実行しなければならない外部プログラムを判断する。プログラマブル Web では、Web サービスクライアントは通常このヘッダーを使用して、エンティティボディに適用するパーサーを判断する。また、Content-Type は Web サービスクライアントがサーバーに送信する表現の種類を識別するためにリクエストヘッダーでも利用される。

❐ 418 I'm a teapot 「私はティーポット」

私はティーポット。HTCPCP/1.0の拡張ステータスコードティーポットにコーヒーを淹れさせようとして、拒否された場合に返すとされる、ジョークのコードである。2017年にこれを除去しようという動きがあったが、反対運動が起こったため、RFC 9110より418は正式に「予約済み」となった。

4-4. 5xx:サーバエラーレスポンス

5xxシリーズのステータスコードは、サーバー側の問題を表すために使用される。ほとんどの場合、これらのコードは、サーバーがクライアントのリクエストを実行する、またはリクエストが正しいかどうかを確認する状態にすらなく、クライアントがそのリクエストをあとから再送すべきであることを意味する。クライアントはサーバー上での問題を解決するために何もできない。
サーバがリクエストの処理に失敗した

5xxシリーズのステータスコードは、サーバー側の問題を表すために使用される。ほとんどの場合、これらのコードは、サーバーがクライアントのリクエストを実行する、またはリクエストが正しいかどうかを確認する状態にすらなく、クライアントがそのリクエストをあとから再送すべきであることを意味する。クライアントがリクエストをどれくらいあとに再送すべきであるかをサーバーが推定し、その情報を Retry After レスポンスヘッダーに設定することができる。

スコーステータスコード5xxの数は、ステータスコード4xxよりも少ないが、それはサーバー上で発生するエラーの数が少ないからではなく、それらのエラーを明確に示すことにあまり意味がないからである。クライアントはサーバー上での問題を解決するために何もできない。

500 Internal Server Error 「サーバ内部エラー」

重要度: 高
関連HTTPメソッド: 全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント

サーバー側で処理方法がわからない事態が発生したことを示します。 これは、汎用のサーバーエラーレスポンスである。ほとんどのWebフレームワークは、例外を 発生させるリクエストハンドラコードを実行する場合に、このステータスコードを送信する。

例として、CGIとして動作させているプログラムに文法エラーがあったり、設定に誤りがあった場合などに返される。

501 Not Implemented 「実装されていない」

重要度: 低
関連HTTPメソッド:全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント

サーバーがサポートしていない HTTP の機能(おそらく拡張機能)をクライアントが使用しようとした、もしくは、リクエストされたメソッドを、このURI でサーバが実装していないことを示します。Web APIなどの仕様上は実装されるべきメソッドとして定義されているにもかかわらず、諸般の都合でサーバが実装していない場合に返ります。サーバがこのメソッドを実装すればクライアントは同じリクエストを繰り返し送れるため5xx系になっています。

たとえばAtomPub では仕様上エントリを削除できますが、 AtomPub を 実装したサーバがDELETE を実装していない場合などに、このステータス コードが返ります。その他、WebDAVが実装されていないサーバに対してWebDAVで使用するメソッド(MOVEやCOPY)を使用した場合に返される。

これはレスポンスコード 405 (Method Not Allowed)に似ているが、405 は、サーバーが認識するメソッドを、クライアントがそれをサポートしないリソースで使用していることを意味する。レスポンスコード 501 は、サーバーがメソッドを認識しないことを意味する。

502 Bad Gateway 「不正なゲートウェイ

重要度: 低
関連HTTPメソッド:全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント

ゲートウェイ・プロキシサーバは不正な要求を受け取り、これを拒否した。

このエラーレスポンスは、リクエストの処理に必要なレスポンスを受け取るゲートウェイとして動作するサーバーが無効なレスポンスを受け取ったことを示します。

また、このレスポンスコードは、HTTP プロキシからのみ送信される。アップストリームサーバー上の問題ではなく、プロキシ、またはプロキシとアップストリームサーバーの間に問題があることを示す。プロキシがアップストリームサーバーにアクセスできない場合、 レスポンスコードは 504(Gateway Timeout) になる。

503 Service Unavailable 「サービス利用不可」

重要度: 中~高
関連HTTPメソッド:全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント
レスポンスヘッダ: Retry After

このステータスコードは、 HTTP サーバーが稼動しているが、 Web サービスが正常に動作していないことを意味する。 ほとんどの場合、原因はリソースの不足である。 一度に受信したリクエストの数が多すぎて、サービスがそれらすべてに対処できないことを示す。

繰り返し送信されるクライアントリクエストがおそらく問題の原因なので、 HTTP サーバーは、ただレスポンスコード503を送信する代わりに、クライアントのリクエストの受信自体を拒否する選択肢を持つ。 サーバーは、リクエストの送信をいつ再開できるかをクライアントに示す、 Retry After ヘッダーを送信することがある。

504 Gateway Timeoutゲートウェイタイムアウト

重要度: 低
関連HTTPメソッド:全て
ボデイ: リクエストが拒否された理由を説明する任意のドキュメント

このエラーレスポンスは、ゲートウェイとして動作するサーバーが時間内にレスポンスを得られない場合に送られます。

502 (Bad Gateway) と同様に、 HTTP プロキシからのみ送信される。このステータスコードは、 ゲートウェイ・プロキシサーバはURIから推測されるアップストリームサーバーからの適切なレスポンスがなくタイムアウトしたことを示す。

❐ 505 HTTP Version Not Supported 「サポートしていないHTTPバージョン」

重要度: 非常に低い
関連HTTPメソッド:全て
ボデイ: そのバージョンが何故サポートされないか, およびサーバーがサポートしているプロトコルを示すドキュメントを追加すべき

リクエストがサポートされていないHTTPバージョンである場合に返される。

5. その他のよく使用される HTTPヘッダー

◎ User-Agent

タイプ: リクエストヘッダー
重要度: 高
値: クライアントソフトウェアの名称とバージョン

このヘッダーを使用して、 サーバーはHTTP リクエストを送信しているソフトウェアの種類を知ることができる。

最近のほぼすべてのブラウザは、 Mozilla のふりをする。それが最初に普及した Web プラウザ (Netscape Navigator) の社内コードネームだったからだ。 Mozilla のふりをしないブラウザは、必要な表現を取得しないことがある。 ブラウザによっては、Internet Explorer 用のコードを呼び出せるように、 MozillaMSIE の両方のふりをするものがある。

Web サービスが User-Agent を使用するのは、統計情報の収集と、うまくプログラムされていないクライアントへのアクセス拒否に 限定すべきである。 特定のクライアントに合わせて表現を調整するために User-Agent を使用すべきではない。

◎ Host

タイプ: リクエストヘッダー
重要度: 必須
値: ホスト名とポート番号

このヘッダーには、URIドメイン名部分が含まれる。クライアントが http://www.example.com/page.html への GET リクエストを送信した場合、 URIパスは 「/page.html」 であり、 Host ヘッ ダーの値は 「www.example.com」 または 「www.example.com:80」 である。

クライアントの観点からすると、これが必須ヘッダーであるのは奇妙に思えるかもしれないこ のヘッダーが必須である理由は、HTTP 1.1 サーバーが単一のIPアドレスで任意数のドメインをホストできることにある。

この機能は「名前ベースの仮想ホスティング」と呼ばれ、複数のドメインを所有する場合に、ドメインごとに個別のコンピュータやネットワークカードを購入する必要をなくす。 問題は、HTTP クライアントがドメイン名ではなくIPアドレスにリクエストを送信することである。Host ヘッダーがなければ、サーバーはどの仮想ホストがクライアントのリクエストのターゲットなのか皆目わからない。

◎ ヘッダー Content-Length

タイプ: リクエスト・レスポンスヘッダー
重要度: 高
値: 10進数の値(バイト)

このレスポンスヘッダーは、ボディのサイズをバイト数で示す。この値は2つの点で重要である。

まず、クライアントがこの値を読み取り、小さなボディまたは大きなボディに備えることができる。 次に、エンティティボディを実際にリクエストしなく ても、クライアントが HEAD リクエストを送信して、ボディのサイズを調べることができる。

Content-Length の値は、クライアントがボディをすべて取得するか、 Range でその一部を取得するか、または取得しないことへの決断に影響をおよぼす可能性がある。

タイプ: リクエストヘッダー
重要度: 従来の Web では高く、プログラマブル Webでは低い
値: 文字列

おそらく、 Content-Type に次いで、2番目に最もよく知られているHTTPヘッダーだが、 HTTP 仕様には含まれていない。このヘッダーは Netscape 拡張です。

Cookie は、クライアントとサーバー間の合意であり、サーバーは Set Cookie ヘッダーを使用して、 クライアント側に半永続的な状態を格納する。 Cookie を取得したクライアントはそれ以降、 Cookie ごとにCookie ヘッダーを一度設定することにより、サーバーへのすべての HTTP リクエストで Cookie を返すことが期待される。データはリクエストごとに HTTPヘッダーに隠れた状態で送信されるため、これはクライアントとサーバーが状態を共有しているようなものである。

Cookieは2つの理由により、REST 界での評判が悪い。まず、Cookie に含まれている「状態」は、多くの場合、単なるセッションID (つまり、サーバー上のはるかに大きいデータ構造に関連付けられた短い英数字キー)である。これは、ステートレス性の原理に反している。さらに巧妙なことに、Cookie を受け取ったクライアントは、それから一定期間にわたって、すべてのリクエストでCookie を送信することになる。サーバーは、Cookie を取得する以前のリクエストはもはや送信できないことをクライアントに伝えている。これも、ステートレス性の原理に反している。

Cookie を使用しなければならない場合は、クライアント側にすべての状態を格納するようにすること。そうしないと、REST のメリットであるスケーラビリティの大半を失うことになる。

タイプ: レスポンスヘッダー
重要度: 従来の Web では高く、プログラマブル Webでは低い
値: 文字列

セッション情報などをサーバからクライアントに設定する際に使用します。

クライアント側の Cookie に何らかの半永続的な状態をサーバー側で設定する試みです。クライアントは、Cookie の有効期限が切れるまで、それ以降のすべてのリクエストで適切な Cookie ヘッダーを送信する。クライアントがこのヘッダーを無視することもあるが(そして、従来の Web では、多くの場合、それはよいことである)、Cookie ヘッダーを提供する場合を除き、それ以降リクエストで適切なレスポンスが得られるという保証はない。これはステートレス性の原理に反している。