RESTによるソフトウェア設計とは何なのかを解剖してみた

## はじめに

RESTって何ですか？

という人はぜひ最後まで読んでみてください。

RESTというのは、Webにおけるソフトウェア設計の共通方式です。
と言ってもピンとこないかもしれません。

が、RESTは昨今のWeb通信技術に広く浸透しているということがあり、RESTの考え方を元に作成された**“RESTful API”**を用いてWebアプリケーション開発が行われることが割と一般的です。

このQiita記事ではその**「RESTの考え方って何だよ？」**というところを解説したので、今後のWebアプリ開発の知識としてもらえたらと思います。
<br>

ちなみにRESTは、

- REpresentational : 具象的な
- State: 状態
- Transfer: 転写

の略です。
<br>

## 1. 統一インターフェース

ほぼ全てのコンピュータには、データへのアクセスの仕方として

- **データを新規作成する**
- **データを読む**
- **データを更新する**
- **データを削除する**

の4機能が実装されています。
これらの動作を**「Create, Read, Update, Delete」**の頭文字から**「CRUD(クラッド)」**と言いますが、これらCRUDに対応したHTTPのメソッド

- **Create → POST**
- **Read →　GET**
- **Update →PUT**
- **Delete　→ DELETE**

を使うとあらかじめ取り決めておくことで、システム全体の実装をシンプルにすることができます。

WebアプリケーションフレームワークのRuby on Railsでは、config/routes.dbに書いたルーティングのメソッド名にget, post, deleteは頻出しますが、共通のHTTPメソッドを使うという取り決めを遵守しているということですね。
<br>

## 2. クライアント/サーバシステム

今あなたがこの記事を見ているPCは**「クライアント」**の役割を持ち、**「サーバ」**というこのブログの記事データを置いているPCに対して**「記事の内容の要求(リクエスト)」**を送ることで、記事を閲覧することができます。

これにより記事を見るあなたのPCであるクライアントはマルチプラットフォームに対応させられます。
この記事はPCからでもスマホからでも閲覧ができます。

また、クライアントが記事データを持ち合わせる必要がなく、サーバもまた記事データを全て溜め込んでおき、来たリクエストにあわせて記事データを提供するだけでよくなり、シンプルな設計になります。
<br>

## 3.ステートレスサーバ
**「ステート: state」**とは状態という意味です。
すなわちステートレスサーバとは、**「サーバがクライアントの状態を持たない」**という意味です。

クライアントがリクエストを送るとき、クライアントの記録している情報は逐一リクエストに送ることを取り決めます。

それによりサーバはそのリクエストに対するレスポンスを返したのち、リクエストを保持することなく破棄することで、**「単にリクエストが来たらそれに対応するレスポンスを返す」**装置として実装することができます。
実装が簡便になるのです。

ステートレスの反対は**「ステートフル」**と言い、サーバがクライアントの状態を保持したまま通信を続けます。

ステートフル・ステートレスとは直感的には以下のようなことを指します。
あなたはファミリーレストランで注文を行うお客さんです。
これをWebにおける**「クライアント」**とします。

注文を受ける店員は**「サーバ」**とします。
そのやりとりがもし**「ステートフル」**だとこのようになります。

### ステートフルなクライアント・サーバシステム

`客：「注文をお願いします」`
店員：「ご注文をお伺いします」
`客：「和牛ステーキセットを1つ」`
店員：「和牛ステーキセットですね、焼き加減はいかがいたしましょうか」
`客：「ミディアムで」`
店員：「ステーキソースはいかがいたしましょうか」
`客：「バーベキューソースで」`
店員：「メインがパンとライスからお選びいただけますがいかがいたしましょうか」
`客：「メインはライスで」`
店員：「サラダドレッシングは和風とオーロラからお選びいただけますがいかがいたしましょうか」
`客：「オーロラドレッシングサラダで。注文は以上です」`
店員：「かしこまりました」

色々な手続きをこなす普通のやりとりです。
これがもし**「ステートレス」**だと以下のようになります。

### ステートレスなクライアント・サーバシステム

`客：「注文をお願いします」`
店員：「ご注文をお伺いします」
`客：「和牛ステーキセットを1つ、注文をお願いします」`
店員：「和牛ステーキセットですね、焼き加減はいかがいたしましょうか」
`客：「ミディアムで和牛ステーキセットを1つ、注文をお願いします」`
店員：「ステーキソースはいかがいたしましょうか」
`客：「バーベキューソースのミディアムで和牛ステーキセットを1つ、注文をお願いします」`
店員：「メインがパンとライスからお選びいただけますがいかがいたしましょうか」
`客：「メインはライスで、バーベキューソースのミディアムで和牛ステーキセットを1つ、注文をお願いします」`
店員：「サラダドレッシングは和風とオーロラからお選びいただけますがいかがいたしましょうか」
`客：「オーロラドレッシングサラダで、メインはライスで、バーベキューソースのミディアムで和牛ステーキセットを1つ、注文をお願いします。注文は以上です」`
店員：「かしこまりました」

あまりに冗長なやりとりですよね。

**「ステートフル」**な状態では、店員が客の注文状態を覚えていました。
だから客は繰り返し同じことを言う必要がなく、聞かれたことに対する情報のみを提供します。

この店員(サーバ)が保持しておく客(クライアント)の以前の情報を**「セッション」**や**「状態」**と言います。

**「ステートレス」**な状態では、店員は客の注文を保持できません。
なので客が今までの情報をすべてひとまとめにして逐一提供し直す必要があります。

PCのサーバは上記の店員とは違い、同じ時間に複数のクライアントからのリクエストが集中するかもしれません。

状態を覚えておくサーバは、一つのリクエストを対応している間は他のリクエストに対応することができません。
そこでクライアントがリクエストごとに全ての情報を逐一提供することで、サーバは複数のリクエストに対する応答(レスポンス)を送ることが出来ます。

すなわち**ステートレスサーバは、サーバが一度に処理するリクエスト数を増やす観点から合理的**なのです。

現実にはサーバはクライアントのログイン状態などを保持しますので、昨今のWebサーバは完全なステートレスではないとする主張が優勢です。
<br>

## 4. 階層型URI

URIとは**「Uniform Resource Identifier」**で、情報の名前や場所を表す書き方の総称のことをさします。

実は我々がよく知るURLとは**「Uniform Resource Locator」**で、URIのうち**「場所:情報がどこにあるか」**をさすものなのです。

URLおよびURIの役割は、**欲しい情報を一意に特定**することです。
Web上である情報は重複することなく一つのURIと対応しているという原則のもと、URLにアクセスすることで、その情報を得ることができるのです。

例えば https://www.google.com のURLにアクセスすることで、我々はいつでも決まったGoogleのホームページを閲覧することができます。

またこのURLで閲覧できるサイトが、勝手に他のサイトにすり替わったりすることはありません(Google社がサイトの仕様を変更しない限りは)

**「階層型URI」**とは、URIによって特定されている情報が階層によって識別されるという考え方です。

YahooオークションAPIの、カテゴリーリスト
https://auctions.yahooapis.jp/AuctionWebService/V2/categoryTree

Amazon Kindleの検索画面
https://www.amazon.co.jp/Kindle-キンドル-電子書籍/b?ie=UTF8&node=xxxxxxxxxxxxxxxx

豊島区役所ホームページの文化カテゴリースポーツ特集記事一覧
https://www.city.toshima.lg.jp/bunka/sports/index.html

`/`でURLを分割し、より詳細度の高い情報階層を表現して、様々な情報を**「一意に」**提供することができるのが階層型URLの考え方です。
<br>