Cowboy 現代のWeb

[Cowboy Users Guide の翻訳記事の目次はこちらへ](http://qiita.com/hayabusa333/items/ac692bdb08fa3d81e312)

# 本文
Webの始まりから今日までのさまざまなWeb技術を見てみることによって、次に何がくるのかの予測を得てみましょう
Cowboyは、この記事を書いている時点で仕様として実現例のないHTTP/2.0以外のすべてのテクノロジーと互換性を持っています。

## 先史時代のWeb
HTTPは最初はHTMLページを提供するためだけに作成され、HTMLページを取得するためのGETメソッドのみを持っていました。
この最初のバージョンは文書化され、HTTP/0.9と呼ばれています。
HTTP/1.0はGET、HEAD、POSTメソッドを定義し、POSTリクエストを使用してデータを送信することができました。

HTTP1.0は非常に簡単な方法で実装されたものです
TCP接続が最初にサーバと確立されます。
次に要求が送信されます。そしてサーバは応答を送り返し、接続を終えます。

HTTP1.0はそんなに効率的というわけではありませんでした、とだけ言っておきましょう。
TCP接続を開始することは多少なりとも時間がかかります、そして多くのリソースを含むページを開こうとしたときはそれゆえに本来可能なはずの速度よりずっと遅いロードになってしまいました。

その後に行われたほとんど改善は、このロード時間を短縮し、要求の待ち時間を減らすことに焦点があてられました。

## HTTP/1.1
HTTP/1.1はHTTP/1.0のあとすぐに登場しました。同じ接続を多数のリクエストだけではなくストリーミング機能にも使えるkeep-alive機構を追加し、エンドポイントに明確に定義されたチャンクの形でbody部を送れるようにしました。

HTTP/1.1はHEAD、OPTIONS、 GET、 HEAD、 POST、 PUT、 DELETE、 TRACE、CONNECTメソッドを定義しています。後年になってPATCHメソッドも追加されました。HTTP/1.1は多くのヘッダの導入によりキャッシュ機能を向上させています。

HTTP/1.1は後続のリクエストのために接続が有効であり続けていることを除けばHTTP/1.0と同じように動作します。しかしながらHTTP/1.1はクライアントがパイプラインと呼ばれるものを実行するできるようにしました（立て続けに多くの要求を送信して、要求と同じ順序で受け取ることになるレスポンスを処理すること）

## REST
HTTP/1.1の設計はRESTアーキテクチャのスタイルの影響を受けていました。
REST、またはREpresentational State Transferは緩やかに接続された分散システムのためのアーキテクチャの形です。

RESTはシステムがRESTfulであるために従わなければならない制約を定めています。
すべての制約に従っていないシステムはRESTfulとは考えられません。

RESTはクライアントとサーバ間の関連事項を明確に分離した クライアントサーバアーキテクチャです。
クライアントはリソースを参照することで通信します。
リソースは特定されるだけではなく操作することができます。
リソース表現はキャッシュできるかどうか、またどのようにキャッシュできるかについて表すメディアタイプ情報を持っています。
ハイパーメディアはリソースがどのような関連があるのかどのように使えるのかを決定します。RESTはまたステートレスでもあります。全ての要求はアクションを実行するために必要な情報が全て含まれています。

HTTP/1.1はRESTfulシステムを実装するために必要な全てのメソッド、ヘッダ及びセマンティクスを定義しています。

一般的に直接実行可能なコードにて使用することを意図しているWebアプリケーションAPIを設計する際にRESTは最もよく使われます。

## XmlHttpRequest
AJAXとしても知られているこの技術はWebページ上で実行されているJavaScriptコードとサーバへの非同期処理を実行することを可能にします。これは静的なWebサイトから動的なWebアプリケーションへの移行を開始した始まりでもあります。

XmlHttpRequestはシステムの裏側でHTTPリクエストを実行してレスポンスを待ちます。ですがJavaScriptコードはレスポンスが返ってくるまで動作し続けることができます。その後JavaScriptコードは予め定義されたコールバックを通してレスポンスを受け付けます。

これはもちろんクライアント側から始められたリクエストであり、サーバ側はそれ自体ではクライアント側へデータをプッシュする方法はまだありませんでした。そこでそれを可能にする新しい技術が登場したのです。

## ロングポーリング
ポーリングはサーバからクライアントへ直接データを送ることができなかったため、それを解決するために使用される技術でした。
したがってクライアントが繰り返し接続を作成し、リクエストを生成し、レスポンスを受け取り、数秒後に再試行する必要がありました。
これではコストがかかりすぎであり、クライアントがデータを受信する前に追加の遅延が発生します。

ポーリングはユーザーが次のページヘと更新する場合ではなく、何かが起きた場合に必ず何か通知される必要があるような場合に対し、メッセージキューや類似の機構を実装するために必要でした。典型的な例はチャットアプリケーションでしょう。

ロングポーリングはより少ない接続の確立で実施することによってサーバの負荷を減らす目的で作られましたが、それだけではなくサーバ上で利用可能になるとすぐにクライアント側へ応答を返すことにより遅延を改善する目的もありました。

ロングポーリングは要求に対してすぐにリクエストを返さないことを除いて、ポーリングと同等に動作します。その代わりロングポーリングが返信するリクエストを有するまでサーバは接続を開いたままにします。レスポンスを取得した後、クライアントは新しいリクエストを作成し待機中に戻ります。

あなたはおそらくロングポーリングが一種のハックではないかと推測されたでしょう。そして多くのハックが予期しなかった問題に苦しめられるように今回の場合、ロングポーリングはプロキシがあるとうまく接続できないのです。

## HTML5
HTML5はもちろんHTML4の後継のHTMLのバージョンです。
しかしHTML5は特定の問題解決のために登場したのです：それは動的なWebアプリケーションです。

HTMLは本来Webサイトを構築するためのWebページを記述するために作成されました。しかしすぐに人々や企業はWebアプリケーションとして知られている、より複雑なウェブサイトを書くためにHTMLを使用したがるようになりました。
例えばニュースリーダーやブラウザ上の電子メールクライアント、またはビデオストリーミングサイトなどです。

HTMLはそれには不十分だったので、彼らは独自のソリューションをときにはプラグインを使用して実装しました。これはもちろん完璧ではありませんでしたが、大多数の人のためには十分な動きをしました。

しかし結局のところ標準化の必要性が明らかになってきました。ブラウザが最初からメディアを再生できるように実装されなければならなくなりました。ブラウザはまた何でも描画できるようになる必要も出てきました。さらにブラウザはサーバーにイベントをストリーミングするだけではなく、サーバーからイベントを受信する効率的な方法を必要としました。

解決策はHTML5で行うこととなりました。執筆時点では、それが標準化されています。

## EventSource
EventSource(またはServer Sent Eventsと呼ばれる)は、サーバーはHTML5アプリケーションにデータをプッシュすることができる技術です。

EventSourceはサーバからクライアントへの一方行の通信チャネルです。
クライアントはHTTPリクエストを使用するしかサーバーと話す方法がありません。

これはあるEventSourceをセットアップすることができるJavascriptオブジェクトとHTTP/1.1接続の上でクライアントにイベントを送出する非常に小さなプロトコルからできています。

EventSourceはUTF-8でエンコードされたテキストデータで動く軽量なソリューションです。バイナリデータと異なるエンコーディングのテキストデータはプロトコルでは許可されていません。より重い、しかしより汎用的なアプローチはWebsocketに見出すことができます。

## Websocket

WebsocketはHTTP1.1にてクライアントとサーバ間の双方向の通信チャネルを提供するために構築されたプロトコルです。通信は非同期的に同時並行的に発生します。

これはWebsocket通信をサーバーとセットアップできるJavascriptオブジェクトとサーバーまたはクライアントにデータを送信するバイナリベースのプロトコルから構成されています。

Websocketの接続は、UTF-8でエンコードされたテキストデータかバイナリデータのどちらも転送することができます。プロトコルはサーバーとクライアントで接続がまだ生きているかどうかをより確実に知ることができるよう、ping/pong通信機構の実装のサポートが含まれています。

Websocket接続は大きくても小さくてもテキストでもバイナリでもどんな種類のデータを転送するのにも使えます。このためWebsocketはシステム間の通信に使用されることもあります。

## SPDY

SPDYはサーバーごとにひとつの接続をオープンし、後続のリクエストのためにそれをオープンしたままにし、さらにHTTPヘッダを圧縮してリクエストのサイズを小さくすることでページのロード時間を短縮するための試みです。

SPDYはHTTP/1.1のセマンティクスと互換性がありますが、HTTPリクエストとレスポンスを実行するやり方としてテキストベースのプロトコルの代わりにバイナリフレームを使用するという点だけが異なっています。SPDYはあるリクエストに続けてサーバーが追加のレスポンスを返すことを認めています。このことはクライアントが要求する前にサーバーがリクエストに関連したリソースを送れて、Webサイトのローディングの際の遅延を少なくできることを意味します。

SPDYは実験の結果うまく動作することが証明され、HTTP/2.0標準の基礎として使われています。

ブラウザはTLS Next Protocol Negotiationを使って、もしプロトコルがSPDYをサポートしていればシームレスにSPDY接続にアップグレードすることができます。

このプロトコルはいくつか足りない点がありますが、それらはHTTP/2.0で修正されます。

## HTTP/2.0

HTTP/2.0はHTTP/1.1の待望のアップデートです。SPDYを基にしておりこの記事を書いている時点でも既に多数の改良が施されています。

HTTP/2.0は2つのエンドポイント間の非同期双方向通信チャネルです。

これは2014年の終わり頃に仕様制定完了予定です[^1]。

[^1]: 実際には2015年2月17日に正式な仕様として承認され、同年5月にRFC 7560として文書化されました。