前回は、「クールなURIは変わらない」と言われるURIの設計についてまとめた。ここでは、TCP/IPをベースとしたプロトコルであるHTTPの基本構造と、クライアントとサーバのやりとり、そしてステートレス性について解説する。
1 HTTPの重要性
HTTPはRFC 2616で規定されたプロトコルである。HTTPはRESTの重要な特徴である統一インタフェース、ステートレスサーバ、キャッシュなどを実現している。現在最も広く利用されているHTTPのバージョンは1.1である。
HTTPはハイパーテキストの転送用プロトコルだが、実際にはHTMLやXMLなどのハイパーテキストだけではなく、静止画、音声、動画、JavaScriptプログラム、PDFや各種オフィスドキュメントファイルなど、コンピュータで扱えるデータであれば何でも転送することができる。
2 TCP/IPとは何か
TCP(Transmission Control Protocol)とIP(Internet Protocol)は、インターネットの基盤を構成する重要なネットワークプロトコルである(コンピュータ同士がつながることネットワーク基礎知識7選も参照)。
階層型プロトコル
インターネットのネットワークプロトコルは階層性になっている。下位層から順に、ネットワークインタフェース層(イーサネット)、インターネット層(IP)、トランスポート層(UDP、TCP)、アプリケーション層(HTTP、NTP、SSH、SMTP、DNS)となっている。層ごとに抽象化して実装することで、下位層の具体的なことに左右されずに上位層を実装することができる。
ネットワークインタフェース層
ネットワークインタフェース層とは、物理的なケーブルやネットワークアダプタに相当する部分である。
インターネット層
インターネット層とは、ネットワークでデータを実際にやり取りする部分である。TCP/IPではIPが相当する。IPでは、データの基本的な通信単位をパケット(Packet)と呼ぶ。指定したIPアドレスを送り先として、パケット単位でデータをやり取りして通信する。IPでは、データ送信は保証するが、そのデータが受信されるかどうかは保証しない。
トランスポート層
トランスポート層とは、IPが保証しなかったデータの転送を保証する部分である。TCP/IPではTCPが相当する。TCPでは接続先の相手に対してコネクションを張る。このコネクションを使ってデータの抜け漏れをチェックし、データの到達を保証する。TCPで接続したコネクションで転送するデータが、どのアプリケーションに渡るかを決定するのがポート番号である。
アプリケーション層
アプリケーション層とは、メールやDNS、HTTPといった具体的なインターネットアプリケーションを実現する部分である。TCPでプログラムを作るときは、ソケット(Socket)と呼ばれるライブラリを使うのが一般的である。ソケットはネットワークでのデータのやり取りを抽象化したAPIで、接続、送信、受信、切断などの基本的な機能を備えている(詳細はTCP/IPデータを電信送信プロトコル・スタックとLANアダプタ)。HTTPサーバやブラウザはソケットを用いて実装する。
3 HTTPのバージョン
HTTP 0.9—HTTPの誕生
HTTP 0.9とは、Berners-Leeが1990年にWebを発明したときに使っていたプロトコルのことである。特徴は、ヘッダがないことと、HTTPメソッドがGETのみであること。HTTP 0.9は現在ではほとんど使われることがない。
HTTP 1.0—HTTP最初の標準化
HTTP 1.0は、IETFで標準化が行われた最初のバージョンである。HTTP 1.0の最初のドラフトは1993年に公開され、3年後の1996年に最終バージョン(RFC 1945)が公開された。HTTP 1.0では、ヘッダの導入、GET以外のメソッドの追加など、HTTP 1.1につながる基本的な要素が盛り込まれた。
HTTP 1.1—HTTPの完成
HTTP 1.1が今後解説する仕様である。HTTP 1.1の最初のバージョンはRFC 2068として1997年に策定された。その後改定が行われ、1999年にRFC 2616が発行されている。RFC 2616が現在のHTTP 1.1仕様である。HTTP 1.1では、HTTP 1.0の機能に加え、チャンク転送、Acceptヘッダによるコンテントネゴシエーション、複雑なキャッシュコントロール、持続的接続などの機能を追加している。
その後のHTTP
その後も議論は続けられているが、それ以上のバージョンアップは行われていない。
4 クライアントとサーバ
Webはアーキテクチャスタイルにクライアント/サーバを採用している。すなわち、クライアント(Webブラウザ)が情報を提供するサーバ(Webサーバ)に接続し、各種のリクエスト(Request,要求)を出してレスポンス(Response,返答)を受け取るというものである。
5 リクエストとレスポンス
リクエスト/レスポンス型(Request-Response Style)プロトコルとは、クライアントが出したリクエストをサーバで処理してレスポンスを返すというものである。サーバでの処理に時間がかかる場合でも、リクエストを出したクライアントはレスポンスが返るまで待機する。これはHTTPが同期型(Synchronous)のプロトコルであるためである。
クライアントで行われること
クライアントでは、1つのリクエストを送信しレスポンスを受信する際に、次の6つの作業を行う。
- リクエストメッセージの構築
- リクエストメッセージの送信
- (レスポンスが返るまで待機)
- レスポンスメッセージの受信
- レスポンスメッセージの解析
- クライアントの目的を達成するために必要な処理
6.の例としては、ブラウザであればHTMLをレンダリングしてウィンドウに表示する処理、検索エンジン用にデータを集めるロボットプログラムであればHTMLの解析結果をデータベースに格納する処理である。
サーバで行われること
クライアントからリクエストを受けたサーバは、次の7つの作業を行う。
- (リクエストの待機)
- リクエストメッセージの受信
- リクエストメッセージの解析
- 適切なアプリケーションプログラムへの処理の委譲
- アプリケーションプログラムから結果を取得
- レスポンスメッセージの構築
- レスポンスメッセージの送信
3.の例は、データベースから最新記事の取得や広告へのリンク生成など。
6 HTTPメッセージ
HTTPメッセージとは、リクエストメッセージとレスポンスメッセージをまとめたものである。
リクエストメッセージ
リクエストライン
リクエストメッセージの1行目はリクエストライン(Request-Line)と呼び、メソッド(GET)、リクエストURI(/test)、プロトコルバージョン(HTTP/1.1)からなる。メソッドには、URIで識別するサーバ上のリソースに対する処理を指定する。リクエストURIは、パス以降の文字列か絶対URIになる。
ヘッダ
リクエストメッセージの2行目以降はヘッダが続く。ヘッダはメッセージのメタデータ(データを記述するデータ)である。1つのメッセージには複数のヘッダを持つことができる。各ヘッダは「名前:値」という構成をしている。
ボディ
ヘッダの後にボディが続くこともある。ボディには、そのメッセージを表す本質的な情報が入る。
レスポンスメッセージ
ステータスライン
レスポンスメッセージの1行目はステータスライン(Status Line)と呼び、プロトコルバージョン(HTTP/1.1)、ステータスコード(200)、テキストフレーズ(OK)からなる。ステータスコードは、リクエストの結果をプログラムで処理可能な数値コードで表現する。
ヘッダ
レスポンスメッセージの2行目以降はヘッダである。
ボディ
ヘッダに続いてボディが続くこともある。ヘッダとボディは空行で区切られる。
HTTPメッセージの構成要素
HTTPメッセージの構造を整理すると、上から順にスタートライン、ヘッダ、空行、ボディという構造になる。
1行目はスタートライン(Start Line)と総称される。次にヘッダが並ぶ。ヘッダ各行の改行はCRLFである。ヘッダの終了は空行で識別する。ヘッダは省略できる。さらに続いて、ボディを持つことができる。ボディにはテキストだけでなく、バイナリデータも入れられる。ボディも省略できる。
7 HTTPのステートレス性
ステートレスとはサーバがクライアントのアプリケーション状態を保存しない制約のことである。
ハンバーガーショップの例
ステートフルなやりとり(日常会話)と、ステートレスなやり取りの違いは以下の4つが挙げられる。
- ステートフルなやりとりは簡潔
- ステートレスなやりとりは冗長
- ステートフルなやりとりでは、サーバがクライアントのそれまでの注文を覚えている
- ステートレスなやりとりでは、クライアントは毎回すべての注文を繰り返している
アプリケーション状態
アプリケーション状態とは、セッション状態(Session State)とも呼ばれ、システムにログインしてからログアウトするまでの一連の操作をまとめてセッションという。ステートフルなプロトコルの代表例はFTPである。
ステートフルの欠点
ステートフルの欠点は、クライアントの数が増えた場合にスケールアウト(サーバの数を増やすことによる性能向上)させにくくなることである。それは、1つのサーバが同時に相手をできるクライアントの数には上限があるからである。
ステートレスの利点
ステートレスの利点は、この問題を解決できることである。クライアントが自らのアプリケーション状態を覚え、すべてのリクエストを自己記述的メッセージ(Self Descriptive Message)で送信することで、スケールアウトが容易になるのである。自己記述的メッセージとは、リクエストの処理に必要な情報がすべて含まれているメッセージである。
ステートレスの欠点
ステートレスの欠点は、パフォーマンスの低下と通信エラーへの対処である。パフォーマンスの低下とは、送信するデータ量が多くなり、認証などサーバに負荷がかかる処理を繰り返すことからもたらされる。通信エラーへの対処とは、ネットワークトラブルが起きたときに、そのリクエストが処理されたかどうかがわからないということである。
8 シンプルなプロトコルであることの強み
HTTPの特長はシンプルさである。HTTPがシンプルだからこそ、ブラウザはPCだけでなく様々なデバイス上でも実装されており、WebサービスとWeb APIが同じプロトコルで実現できているのである。
最後に
HTTPはTCP/IPをベースとしたプロトコルであり、そのプロトコルは階層型になっている。クライアントとサーバのやりとりでは、リクエスト/レスポンス型のプロトコルが使われており、それらのメッセージはHTTPメッセージと呼ばれている。ステートレス性とは、サーバがクライアントのアプリケーション状態を保存しない制約のことである。HTTPはそのシンプルさが最大の武器である。
次回は、「Webの成功理由は制約」と言われる8つしかないHTTPメソッドについてまとめる。
![]() |