実践REST　~知識だけでは終わらせない~

# はじめに
**「実践でRESTを使用している方」**

RESTっていろいろルールがあるので簡潔に人に説明するのって意外と難しいよなぁ...

なんとなく理解はしているつもり、URL設計すればいいんでしょ？

**「実践でRESTを使用していない方」**

RESTのルールについていろいろ調べたけど結局どう使うの？


このような方向けに

- 簡潔に人に説明することができるようになる
- 実際の開発で使用するイメージが付く(何を考慮しないといけないのか)

この2点を最終ゴールに設定して記事を作成しました。

特に初心者の方はこの記事でRESTについての概要を知った後で他の方が説明されているより具体的な

記事や教材を読んでいってください。


# RESTとは

**RE**presentational **S**tate **T**ransferの略。

**RE**presentational:表現
**S**tate:状態
**T**ransfer: 転送

状態の転送の仕方の表現？？　意味が分からないのでもっとかみ砕きましょう



状態⇒クライアントとサーバー間でやりとりする情報

表現⇒設計のやり方

ととらえるとわかりやすいです。


RESTとは

**「クライアントサーバーでやり取りする情報の転送方法のための設計手段」**


やり取りする情報を具体的に示すと

サーバーからユーザー一覧情報をJSON形式で取得したい

```json:User一覧情報(JSON形式)
[
    {
        "id": 1,
        "name": "first user"
        "age": 20,
    },
    {
        "id": 2,
        "name": "second user",
        "age": 23,
    },
    ...同じような構造のデータが続いていく
]
```

このような情報をサーバーから受け取り、アプリケーション側でレイアウトを整えてブラウザに表示させる

みたいなときに使用するわけです。



ユーザー一覧・投稿一覧・ユーザー詳細　情報...

全部このような情報はサーバーとのRESTにのっとったやり取りで取得するのが主流です。

またDBに保存されているこのユーザー情報を取得以外にも、更新・削除したい際の

サーバーに送る命令も立派なRESTがカーバーする情報です。



サーバーからデータ取得する・サーバーの情報に対して更新・削除などの操作をする際に必要なんです！！

大事さが伝わっていただけたでしょうか？


※ちなみにRESTにのっとったAPIをRESTful APIって言ったりします。

# RESTはどういう設計原則なの？

RESTとは
>「クライアントサーバーでやり取りする情報の転送方法のための設計手段」

と書きましたが、実際にはどのような設計を行えばRESTといえるのでしょうか？

以下の4つの原則に沿って行います。

深く理解する必要ないです。30秒くらいで流し読みしてください。


### RESTの4原則

　①統一インターフェース
　②アドレス可能性
　③接続性
　④ステートレス性

簡単に見ていきましょう。

**①統一インターフェース**

　あらかじめ決めておいた方法で情報をやり取りしようねという原則です。
　例えば
- やり取りするデータ形式を　JSONにするかXML形式にする
- GET・POST・PUT・DELETE等のHTTPメソッドを使用してやり取りを行う

　などの決まりごとがあらかじめ決められています。

　Webでは
　**このURL(サーバー)にクライアントからこのHTTPメソッドで送られてきたらこの処理をするよ！
　みたいな紐づけを行います。**

**②アドレス可能性**
　すべての情報が一意なURI(URL)で区別できるよってことです。
　URLをたたいたら30%の確率でUser一覧情報がきて
　70%の確率でCompany一覧情報が来るとかだったら使い物にならないですよね

**③接続性**
　やりとりされる情報にはハイパーリンクを含めることができるよという意味です。
　やり取りされた情報に含まれるハイパーリンクから、関連する情報を取得できるよくらいで大丈夫です。

**④ステートレス性**
　1回のやり取りが独立していることを示しています。
　[ステートレス参考](https://qiita.com/ryoma5457557831/items/cbb6242fb7f6d5d40236)　←どうしても気になってしまう方はどうぞ


正直こんなの暗記する必要ないです。

いろいろなサイトでここら辺を見て結局RESTって？？？

みたいな感じで終わっている方も多いと思います。大事なのは実際にどう応用するかです。



# 実際にREST APIの設計をしてみよう！

> 　**このURL(サーバー)にクライアントからこのHTTPメソッドで送られてきたらこの処理をするよ！
　みたいな紐づけを行います。**

これを実際にやっていこうというわけです。

今回はクライアントとサーバーでやり取りするデータをmovie(動画)データとでもしましょう！


### REST APIで設計する項目
**基本**
- URL設計
- レスポンス設計

**応用**
- キャッシュ設計
- セキュリティ設計
- 認証設計
- 大量アクセス設計


今回は基本的な設計について紹介させていただきます。

応用的な方も気になる方は[こちら](https://www.udemy.com/course/rest-webapi-development/)のudemyで内容を深ぼりしてください。



## 1.URL設計
クライアントからこのURLにリクエストを送信したら

サーバー側のデータを取得したり操作したりするわけですが

このURLだったら多分こういう操作が行われるんだろなーという推測が付くURLがGoodです。


今回のmovieデータに対する操作のURL設計だと


|URL|HTTP METHOD|データに対する操作|
|--|--|--|
|/v1/movies|GET|movieデータ全件取得|
|/v1/movies|POST|movieデータの作成
|/v1/movies/[id]|GET|特定の[id]のmovieデータ取得|
|/v1/movies/[id]|PATCH/PUT|特定の[id]のmovieデータ更新|
|/v1/movies/[id]|DELETE|特定の[id]のmovieデータ削除|

<details><summary>捕捉</summary>

> 実際のURLはドメインが前につきます。
>  例⇒https://expmple.com/v1/movies　みたいな感じ

> /v1の部分はバージョンを表しています。/v2,/v3とかになっていきます。

> [id]の部分は
> /vi/movies/1/edit
> みたいな感じになり、特定のid(今回は1)のmovieに対しての操作を行います。
</details>

***コツ***

- URL⇒どのリソースに対して
- HTTP METHOD⇒どの操作を行うのか

を意識しましょう。

例えば

/vi/movies  ⇒　movie全件のデータに対して
GET⇒取得
POST⇒データ追加

***Tips***
- 短く簡潔に
- 人間にとってわかりやすいURL
- すべて小文字
- 単語はハイフンでつなげる
- 日本語などURLエンコードされる文字は使用しない

ここら辺を意識するだけでだいぶ違います。


最後にクライアント(ブラウザ)からAPIをたたく場合の例

```javascript:javascript
const getMovies = async() => {
    const res = await fetch('https://example.com/v1/movies',{
       headers: {
          'Content-Type': 'application/json'
        },
    });

    if(!res.ok){
        throw new Error('動画一覧取得に失敗しました。');
    }
    try {
        const users = await res.json();
        return users;
    }catch(e){
        throw new Error('Jsonデータのパースに失敗しました。');
    }
    
}
```


## 2.レスポンス設計

3つほど考える必要があります。

- レスポンスbody
- レスポンスヘッダー
- Httpステータスコード


HTTPステータスコードに関しては外部に公開する目的で使用される際には付けたほうがいいと思いますが、

アプリケーション内で使用するだけの簡単なAPIならここまで意識しなくてもいいのかなと思ってます。



例えば
/v1/movies　GET

にリクエストを飛ばした際には


### 成功時

**HTTPステータスコード**
```
通常
200 ok

cacheを使用したときは
304 Not Modified
```

**レスポンスheader**
```
Content-Type: application/json; charset=utf-8
```

**レスポンスbody**
```json: good
[
    {
        "id": 1,
        "title": "RestApiの設計方法"
        "playCount": 300,
        "playbackTime": 120,
    },
    {
        "id": 2,
        "title": "DB設計方法",
        "playCount": 10000,
        "playbackTime": 360,
    },
    ...
]
```


```json: bad
[
    {
        "id": 1,
        "title": "RestApiの設計方法",
        "playerInfo": {
            "count": 300,
            "time": 120
        },
    },
]
```

このようにできるだけネストを含めないようにするのが吉です。

理解のしやすさや、取り出しのしやすさが違ってきます。

### 失敗時

**HTTPステータスコード**
```
クライアント側の不備
400 Bad Request

認証失敗
401 Unauthorized

認可エラー
402 Forbidden

リソースがない
404 Not Found

レートリミット制限(リクエストしすぎ)
429 To Many Requests
```

**レスポンスヘッダ**
特になし


**レスポンスbody**
```json
{
    "message": "データベース接続エラー",
}

```

https://qiita.com/suin/items/f7ac4de914e9f3f35884

↑自分はここら辺を参考にしています。


特にステータスコードまわりめんどくさいですよね苦笑。


ここら辺の設定はRails・Laravel・Djangoなどのフレームワークを使用して行っていきます。


これ以上はフレームワークの説明になってしまうので適宜学習してください。


### 3.その他の設計

基本的なものは上記で十分ですが、

- cahce設計
    ⇒cacheControl, expire, Lst Modifiedヘッダーなど
- Authorizationヘッダーによる認証
    ⇒Basic認証, JWTなど
- 大量アクセス対策
    ⇒Sliding Windowの使用
- セキュリティ対策
    ⇒X-XSS-Protection, X-Frame-Options, X-ContentType-Optionsの指定・CRSF対策・TLSの使用


など応用的ですが大事な部分なので、内容の要点だけ書いたので調べてみてもいいかもしれません。

↓自分はこのudemyの講座で学びました！！

https://www.udemy.com/course/rest-webapi-development/



## さいごに

RESTについての実感がわいてきましたか？

なんとなくでRESTを触っていた方も、RESTってこんな考慮しないといけないことあるの？

と感じて頂けたのではないでしょうか？

あとはフロントの言語(javascript)とサーバーサイドのフレームワークを学んでいくだけです。


どんどんoutputしていきましょう！！