REST APIとは

## はじめに
REST APIについて調べたので備忘録として残します。自分自身まだ理解の甘い部分があるのであくまでも参考程度にご覧いただければ幸いです。

## REST APIとは

REST（Representational State Transfer）APIはWebサービス設計思想の一つです。RESTの設計原則に基づいたAPIを指します。他にもXML-RPC」やSOAPなどのWeb設計思想がありますが、現在主流なのはこのREST APIです。
RESTの設計原則の基づいた設計、開発をすることでシンプルで効率的な開発が可能となります。

## REST APIの設計原則
設計原則には主に以下の６つがあります。

1. クライアントサーバー
2. 階層化システム
3. キャッシュ制御
4. コードオンデマンド
5. 統一インターフェース
6. ステートレス

それぞれ解説します。

### 1. クライアント/サーバー
クライアントとサーバーは独立し、それぞれの責任が分離されます。クライアントはユーザーインターフェースやユーザーエクスペリエンスに焦点を当て、サーバーはデータやロジックに焦点を当てます。それぞれを分離させることで、クライアントとサーバーで相互に影響を及ばさず、開発が可能となります。
    
### 2. 階層化システム
サーバーを役割ごとに細かく分けることを指します。よくあるWebアプリケーションの構成としてWeb、AP、DBの構成も階層化システムに当たります。階層化システムではサーバーひとつ単位のことをコンポーネントと表現することがあります。

### 3. キャッシュ制御
サーバーやクライアントがリソースのキャッシュを管理する仕組みです。適切なキャッシュ制御を使用することで、ネットワークトラフィックの削減やパフォーマンスの向上が実現できます。HTTPヘッダー（例: Cache-Control）を使用してキャッシュ動作を指定します。

### 4. コードオンデマンド
クライアントが必要に応じてサーバーから実行可能なコード（例: JavaScript）を受信し、実行できる仕組みです。サーバー側の負荷を下げるメリットがあります。逆にデメリットはあらゆるクライアント環境を想定して開発をする必要が生じることです。
    
### 5. 統一インターフェース
あらかじめ決められた方法で情報をやり取りすることをさします。WebであればGET, POST, PUT, DELETEなどのHTTPメソッドを利用する。そしてデータはJSON形式でやり取りをするといった具合に統一された手段、ルールで情報を扱うことを定めています。

### 6. ステートレス
各リクエストは完全に独立しており、前のリクエストやセッション情報に依存しません。すべての必要な情報はリクエスト自体に含まれています。つまり、どんな情報を欲しているのかをリクエストを見れば全て記載されている状態になります。

以上、6つのルールに則って設計されたAPIのことをREST API（RESTfulなAPI）と言います。

## HTTPメソッド
REST APIで使われるメソッドは以下の4つがあります。
|  メソッド  |  機能  |  冪等  |  安全  |
|  ----  |  ----  |  ---  |  ---  |
|  GET |  取得  |  ○  |  ○  |
|  POST  |  作成  |  ×  |  ×  |
|  PUT  |  更新  |  ○  |  ×  |
|  DELETE  |  削除  |  ○  |  ×  |

冪等とは同じ操作を何度行っても同じ結果になることです。例えば`api/names/1`というIDが1
のnameを更新するためにnameを「太郎」に更新するPUTリクエストを送信したとします。この操作を何度を行ってもIDが１の人の名前は「太郎」となります。これを冪等と言います。

安全とはリソースに変化が生じるかどうかを示します。前述した表を見るとGET以外は×になっていますね。GETはリソースを取得するだけ、それに対して他のPOST ,PUT, DELETEはリソースに対して変更を加えています。

REST APIではこれらのHTTPメソッドを通して、同じURLに対して様々な処理を割り当てていきます。

## URI
APIにアクセスするためのURIを設計する必要があります。ではどう設計すれば良いか？基本的には以下の点が重要となります。

1. 短くシンプルである
2. 一目で見て理解できる
3. ルールが統一されている
4. 単語は名詞の複数形である
5. サーバー側のアーキテクチャが反映されていない
6. バージョン番号を含む

1〜3は見ての通りです。基本的に必要以上に複雑にしない、わかりやすいことが原則です。誰が見てもどこに何があるか、ぱっと見である程度わかるURIが理想となります。4〜6について補足します。

### 4. 単語は名詞の複数形である
URIはリソースの場所を示しています。つまり何かのデータの塊が入ることになります。よってなんのデータかが分かる名詞、かつ複数形が良いとされています。そのリソースに対して何をするかはHTTPメソッドで表現するので動詞は含めないようにしましょう。

### 5. サーバー側のアーキテクチャが反映されていない
サーバー側の設計がURIに反映されていると、悪意あるユーザーに情報を与えてしまいます。例えば拡張子`.php`などが見えてしまう状態だと、 PHPの脆弱性を突かれ被害を受ける可能性があります。こうした危険を避けるため、サーバー側のアーキテクチャが反映されていない状態が好ましいです。

### 6. バージョン番号を含む
APIを公開後、できれば変更せずに済むのが理想ですが、実際には変更せざるを得ない状況が来るかもしれません。そういった場合に備え、URIにはバージョン番号を含め、新旧のAPIを共存させながら運用できる状態にしておきましょう。新旧どちらを利用するかはクライアントに委ねます。




## 例題
最後に、これまで説明してきたREST APIのルールに従って例題に挑戦してみます。

*movieをリソースとして CRUD操作のURI、HTTPメソッドを定義する*

## 解答
|  URI  |  HTTP method  |
| ---- | ---- |
| /api/movies |  GET  |
|  /api/movies/{id}  |  GET  |
| /api/movies | POST |
| /api/movies/{id} | PUT |
|/api/movies/{id} | DELETE |

## 解説
この例題では映画のリスト（movie）を扱うWebサービスを想定し、CRUD操作のURI、HTTPメソッドを定義することを求めています。
上から順に説明します。

まず映画の一覧を取得する場合には`/api/movies`にGETリクエストを送信します。

そして、特定の映画を取得する場合には`/api/movies/{id}`に対してGETリクエストを送信し、IDを用いて一意の映画を指定して取得します。

新たな映画を登録する場合には`api/movies`に対してPOSTリクエストを送信します。

既存の映画を更新するには`api/movies/{id}`に対してPUTリクエストを送信します。IDを用いて対象の映画を指定しています。

既存の映画を削除するには`api/movies/{id}`に対してDELETEリクエストを送信します。
それぞれの解説を表に加えたものが以下です。

|  URI  |  HTTP method  |  説明  |
| ---- | ---- |  ---  |
| /api/movies |  GET  |  映画の一覧を取得  |
|  /api/movies/{id}  |  GET  |  特定の映画を取得  |
| /api/movies | POST |  映画を新規登録  |
| /api/movies/{id} | PUT |  既存の映画を更新  |
|/api/movies/{id} | DELETE |  既存の映画を削除  |

## 最後に
今回は現代で主流の設計思想「REST API」についてまとめてました。プログラミング技術というより、設計の話は考え方についての話題のため少し難しく感じました。自分の中でもっと良い言語化が浮かんだらまた更新しようと思います。

## 参考文献
- [REST WebAPI サービス 設計](https://www.udemy.com/share/103eNc3@XEKTQj9MCjoJVq3g2tQOlVY86EX-BZjY3q2hyt0rXNhI9wH3JVwY_L9wAj1BkBbucw==/)
- [REST APIとは？ざっくりと理解してみる【初心者向け】](https://tech.012grp.co.jp/entry/rest_api_basics)