RESTを構成する6つのアーキテクチャスタイルの解説

## RESTとは

RESTとは、**Webサービスのアーキテクチャスタイルのひとつ**です。ちなみに、RESTは**RE**presentational **S**tate **T**ransferの略です。

アーキテクチャスタイルという言葉は、私はRESTについて調べるまで知りませんでしたが、Webサービスの設計モデルのことだそうです。デザインパターンはプログラミングにおける指針を示すものですが、アーキテクチャスタイルはさらに高レイヤにおける設計指針です。

RESTの目的は、**分散システムにおいて複数のソフトウェアが連携しやすくすること**だそうです。分散システムとは、ネットワークで接続された複数のコンピュータで作業を分担する仕組みのことです。RESTの制約に従っていることを**RESTful**といいますが、RESTfulになることで、パフォーマンス、スケーラビリティ 、簡潔性、拡張性、可視性、移植性、信頼性に優れたシステムを実現できるらしいです。

### RESTを構成する6つのアーキテクチャスタイル

有名なアーキテクチャスタイルのひとつに**クライアント/サーバ**があります。

クライアント/サーバは、**単一のコンピュータがすべてを処理するのではなく、クライアントとサーバに処理を分散させる設計モデル**です。こうすることで、クライアントとしてPCだけでなく、モバイル端末やゲーム機も利用できるようになるメリットがあります。これを**マルチプラットフォーム**と呼ぶようです。

**RESTは、このクライアント/サーバを派生させたアーキテクチャスタイルです**。

具体的には、次の6つのアーキテクチャスタイルを組み合わせたものがRESTだそうです。

* クライアント/サーバ
* ステートレスサーバ
* キャッシュ
* 統一インタフェース
* 階層化システム
* コードオンデマンド

上記から、RESTと名付けられる前は、**ULCODC$SS**（Uniform Layered Code on Demand Client Cache Stateless Serve）と呼ばれていたようです。

本記事では、RESTを構成する6つのアーキテクチャスタイルについて調べたことを整理していきます。 ※ クライアント/サーバは省略

間違っている箇所などありましたら、ご指摘いただけると大変ありがたいです。

## ステートレスサーバ

ステートとは状態のことですが、Webサービスにおいてはクライアントのセッション情報を指すようです。

ステートレスサーバとは、名前の通り、**サーバがセッション情報などの状態を保持しない**という意味です。これにより、**サーバ側はレスポンスを返すと同時にリソースを解放することができる**ようになります。また、サーバが状態を持たないことで、**サーバの台数を増やしてスケールアウトすることも容易**になります。

### ステートレスにするとスケールアウトしやすい

ステートレスサーバがスケーラビリティの向上につながる、という話を詳しく書きます。

サーバの台数を増やして、トラフィックを分散させることをスケールアウトといいます。このとき、特定のサーバだけがセッション情報を保持しているとすると、リクエストをどのサーバが処理するかによってレスポンスの内容が変わってしまう、という問題が発生します。これを避けるためには、すべてのサーバでセッション情報を共有する必要があるため、オーバヘッドがかかります。

サーバが状態を保持しなければ、このようなスケールアウト時の問題は発生しません。どのサーバがリクエストを処理したとしても同じレスポンスが返ってくるからです。

### ステートフルとステートレスの違い

ステートレスには上記のようなメリットがありますが、無視できないデメリットもあります。

* 送信するデータ量が多くなり、ネットワーク帯域を消費する
* 認証などのサーバに負荷のかかる処理を何度も繰り返す必要がある

これらのデメリットは、サーバがステートフルな場合と比較したときの評価です。ステートフルとは、状態を持つという意味で、ステートレスとは反対の意味です。両者の違いを理解する上で、Webを支える技術という書籍で紹介されていたハンバーガショップの例が大変参考になりましたので引用します。

>  **ステートフルなやりとり**
>
> 客: こんにちは。
> 店員: いらっしゃいませ。○○バーガーへようこそ。
> 客: ハンバーガーセットをお願いします。
> 店員: サイドメニューは何になさいますか?
> 客: ポテトで。
> 店員: ドリンクは何になさいますか?
> 客: コーラで。
> 店員: +50円でドリンクをLサイズにできますがいかがですか?
> 客: Mでいいです。
> 店員: 以上でよろしいですか?
> 客: はい。
> 店員: かしこまりました。
>
> （中略）
>
> **ステートレスなやりとり**
>
> 客: こんにちは。
> 店員: いらっしゃいませ。○○バーガーへようこそ。
> 客: ハンバーガーセットをお願いします。
> 店員: サイドメニューは何になさいますか?
> 客: ハンバーガーセットをポテトでお願いします。
> 店員: ドリンクは何になさいますか?
> 客: ハンバーガーセットをポテトとコーラでお願いします。
> 店員: +50円でドリンクをLサイズにできますがいかがですか?
> 客: ハンバーガーセットをポテトとコーラ(M)でお願いします。
> 店員: 以上でよろしいですか?
> 客: ハンバーガーセットをポテトとコーラ(M)でお願いします。以上。
> 店員: かしこまりました。
>
> [Webを支える技術](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042)

ステートフルなやりとりでは、それまでの注文が記憶されているため、追加の注文は差分のみで済んでいます。一方、**ステートレスなやりとりでは、毎回すべての情報を注文に含めなければならないため冗長**です。

## キャッシュ

キャッシュとは、一度取得したWebページの情報をクライアントのストレージに保存し、次回高速にアクセスできるようにする仕組みのことです。

キャッシュを利用するメリットは、クライアントとサーバ間の通信を減らすことでネットワーク帯域の利用を抑え、レスポンスを高速化することができる点にあります。一方で、Webページの更新情報がキャッシュに反映されていない場合、古いページが表示されてしまうといったデメリットもあります。

## 統一インタフェース

統一インタフェースとは、URIで示したリソースに対する操作を、統一した限定的なインタフェースで行うアーキテクチャスタイルだそうです。具体的には、リソースの操作というのはデータの生成や取得や更新などを指していて、統一したインタフェースとはGETやPOSTなどのHTTPメソッドのことのようです。

この統一インタフェースのおかげで、クライアントとサーバの実装の独立性が向上する、と説明されていました。つまり、HTTPで定義されている8つのメソッドを使って通信する限り、サーバはクライアントが具体的に何であるかを意識せずに済む、ということだと私は解釈しました。

## 階層化システム

階層化システムとは、クライアントとサーバの間にロードバランサを設置して負荷分散をしたり、プロキシを設置してアクセスを制限したりといった階層を構築するアーキテクチャスタイルです。

こうした階層化は、インタフェースが統一されていることにより実現しているようです。クライアントは、サーバもプロキシも同じインタフェースを使って接続できるため、接続先が何であるかを意識せずに済みます。また、HTTPインタフェースを実装していないレガシーなシステムも、間にWebアプリケーションサーバを挟んでHTTPインタフェースを持たせることで、クライアントと接続できるようになるようです。

## コードオンデマンド

コードオンデマンドとは、JavaScriptやFlashなどのプログラムコードを、サーバからダウンロードしてクライアント側で実行するアーキテクチャスタイルです。

コードオンデマンドにより、クライアントには用意されていない新しい機能を追加することができます。JavaScriptの例でいえば、ポップアップを表示したり、フォームの入力値をチェックしたり、といった機能を追加できます。

コードオンデマンドのデメリットとして、ネットワーク通信におけるプロトコルの可視性が低下することが挙げられていました。通常のHTTPレスポンスには、ボディにリソースの表現が含まれますが、コードオンデマンドにより表現をクライアント側で決定する場合はそうではない、という意味だと解釈しました。

## まとめ

RESTとは、Webサービスの設計モデル（アーキテクチャスタイル）のことでした。システム同士が連携しやすくするための設計指針です。

RESTは、次の6つのアーキテクチャスタイルにより構成されています。

| アーキテクチャスタイル | 説明                                                         |
| ---------------------- | ------------------------------------------------------------ |
| クライアント/サーバ    | クライアントとサーバに処理を分離してマルチプラットフォームを実現する |
| ステートレスサーバ     | サーバに状態を持たせないことでスケールアウトしやすくする     |
| キャッシュ             | 一度取得したリソースを次回から高速にアクセスできるようにする |
| 統一インタフェース     | HTTPメソッドを8つに限定してクライアントとサーバの実装の独立性を向上する |
| 階層化システム         | クライアントとサーバの間にロードバランサを設置するなどして階層構造にする |
| コードオンデマンド     | JavaScriptなどのプログラムをダウンロードさせクライアント側で実行する |

これらの制約に従っていることをRESTful、RESTらしいと表現します。

今回、RESTを構成する6つのアーキテクチャについて学びましたが、制約といっても、ほとんど常識になっているものばかりだな、と感じました。それだけRESTというアーキテクチャスタイルが有効だったということだと思います。