Railsチュートリアル完走後に、改めてリソースについてまとめてみた

# 背景
* Railsチュートリアル完走後に､**どのようにして機能を拡張していくか考えたときになんとなく「機能をリソース」として扱えれば､設計がしやすいのでは？**というのが発端｡また、リソースについてもしっかり理解できていなかったので完走したあとに再度情報整理したかった。

# 目的
* 「Railsにおけるリソース」について､構成する要素の関係性についてまとめることで理解を深めてオペレーション時にもすぐに活かせる状態にしたい｡

# RESTの原則
* RailsはRESTの原則に従って設計されている｡
* **RESTとは､ざっくりいうとwebを設計するための考え方のひとつ**｡
* Railsでのリソースを理解するためには､土台であるRESTの原則を知る必要がある｡

## 4つの原則
1. ステートレスなクライアント/サーバプロトコル
2.  すべての情報（リソース）に適用できる「よく定義された操作」のセット
3. リソースを一意に識別する「汎用的な構文」
4. アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」

引用元：[Representational State Transfer \- Wikipedia](https://ja.wikipedia.org/wiki/Representational_State_Transfer#%E5%8E%9F%E5%89%87)

## 1. ステートレスなクライアント/サーバプロトコル
RESTな考え方では､**サーバーへのリクエストも､クライアントへのレスポンスも毎回状態を管理しない(ステートレス)HTTPを使う｡**

メリットとしては､複数のサーバーで複数のクライアントに対してレスポンスする際に効率がよい｡

web設計する際に1つ目の原則に関しては､基本的にHTTPを使っていれば意識しなくて遵守される｡

HTTP(HTTP/1.1)には､8つのメソッドが定義されており､2つ目の原則と関連してくる｡

* GET
* POST
* PUT
* HEAD
* DELETE
* OPTIONS
* TRACE
* CONNECT

引用元：[Hypertext Transfer Protocol \- Wikipedia](https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)

## 2. すべての情報（リソース）に適用できる「よく定義された操作」のセット
RESTな考え方では､**全てのリソースにHTTPメソッド(GET､POST､PUT､DELETEなど)を使ったアクセス可能な共通インターフェイスを持つ｡**

HTTPメソッドは次の役割を持っており、この役割に当てはめて設計を考える｡

| HTTPメソッド | 役割 |
| --- | --- |
| GET | リソースの取得 |
| POST |子リソースの作成､リソースへのデータ追加､その他の処理  |
| PUT | リソースの更新､リソースの作成 |
| DELETE | リソースの削除 |
| HEAD | リソースのヘッダ(メタデータ)の取得 |
| OPTIONS | リソースがサポートしているメソッドの取得 |
| TRACE | 自分宛にリクエストメッセージを返す(ループバック)試験 |
| CONNECT | プロキシ動作のトンネル接続への変更 |

引用：[Webの成功理由は制約 ８つしかないHTTPメソッド](http://kaihooo.com/http-method/)

## 3. リソースを一意に識別する「汎用的な構文」
RESTな考え方では､**全てのリソースはURI(広い概念でURLとURNが含まれる)で表されるユニークなアドレス持つ**

## 4. アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
今ではHTMLページに他のページへのリンクを貼ることは当たり前だが､そのこと｡
これも､意識してなくても基本的に遵守される｡

# RESTfulとは
4つの原則に従って作成されたものを指す｡

# RailsでRESTfulなリソースを作成するために意識すること
Railsにおいて､RESTの原則の1と4に関しては､現在であれば当たり前なのであまり意識せずともよいが､**2と3に関しては意識する必要がある｡**

## 2. すべての情報（リソース）に適用できる「よく定義された操作」のセット
Railsにおいて､2に関しては､具体的にRailsチュートリアル内のコラム 2.2で言及されており、
Railsのリソースは、下記に対応する共通インターフェイスを持っているといえる｡

* **リレーショナルデータベースの作成/取得/更新/削除 (Create/Read/Update/Delete: CRUD) 操作**
* **4つの基本的なHTTPメソッド (POST/GET/PATCH/DELETE)** 

Railsは､RESTの原則を取り入れいち早く対応しているフレームワークでもあり､**共通インターフェイスを持たせるために､HTTPメソッドごとにデータベース上のCRUD操作と対応付けを定義している｡**

Railsのルーティング機能は、RESTの考え方を取り入れる上で、重要。
ルーティングでHTTPメソッドとアクションを紐づけ、webでのCRUD操作を実現する。

下記は､photosリソースの例(CRUD操作の列は､HTTPメソッドとデータベースの繋がりが分かりやすいように追加)｡

| HTTP動詞 | パス | コントローラ#アクション | 目的 |CRUD操作|
| --- | --- | --- | --- | --- |
| GET | /photos | photos#index | すべての写真の一覧を表示 | 取得(R)|
| GET  | /photos/new | photos#new | 写真を1つ作成するためのHTMLフォームを返す | 取得(R) |
| POST | /photos | photos#create | 写真を1つ作成する | 作成(C) |
| GET | /photos/:id | photos#show | 特定の写真を表示する | 取得(R) |
| GET | /photos/:id/edit | photos#edit | 写真編集用のHTMLフォームを1つ返す | 削除(D) |
| PATCH/PUT | /photos/:id | photos#update | 特定の写真を更新する | 更新(U) |
| DELETE | /photos/:id | photos#destroy | 特定の写真を削除する | 削除(D) |

引用元：[Rails のルーティング \- Rails ガイド](https://railsguides.jp/routing.html#rails%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AE%E7%9B%AE%E7%9A%84)の2.2の表参照

HTTPメソッドとURL(パス)を組み合わせて､CRUD操作を実現していることがわかる｡

Railsの良いところは､`resources :photos`を使えば､RESTの考え方に沿った共通インターフェイスができる点｡

## 3. リソースを一意に識別する「汎用的な構文」
RESTの原則の3に関しては､Railsチュートリアルの7章の7.1.2 Usersリソースで少し触れられています｡

> RESTの原則に従う場合、リソースへの参照はリソース名とユニークなIDを使うのが普通です。

他にチュートリアルで良い例が見つけられなかったが下記が参考になった｡

* URLに動詞を含めず、複数形の名詞のみで構成する

[REST APIとは？ \- API設計のポイント](http://wp.tech-style.info/archives/683#toc8)

# リソースを2.2.2 MVCの挙動のMVCモデルの図と使って説明

これらを踏まえた上で、自分のリソースのイメージは､こんな感じです｡

図でいうと､ユーザーから見たインターフェイスは/usersになる｡
/usersのページのリクエスト(HTTPメソッド)を元にCRUD操作と結びつける(ルーターとコントローラの役割。モデルも密接に関わっている)｡

CRUD操作をするためには､データモデルが必要になり､最終的にユーザーから見える/usersに提供するためにビューが必要になる｡

これらが組み合わさり､ユーザーにCRUD操作を提供するオブジェクトがリソース｡これがリソースの正体｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163887/a1681552-c947-ad66-17ee-bb279cf7fc70.png)

# Railsチュートリアルで出てきたリソースを比較してみる｡
一番やりかったのがこれ｡
下記ページのP25をみたときに全体像が分かっていれば､少しリソースの設計がわかりやすくと思ったため｡
[Rest ful api設計入門](https://www.slideshare.net/MonstarLabInc/rest-ful-api)

3章以降で出てくるリソースをRailsのCRUD操作に当てはめてみた(自分が分かりやすいように少し調整)｡

1～3行目までは､すべてのリソースに共通する項目で､4行目は､途中で説明したphotosリソースを例として使っている｡5行目以降がRailsチュートリアルで出てくるリソース｡

すべてのアクションを使っていないリソースがあったり、用途に合わせてパスを調整しているリソースもあったりすることがわかる。

| 目的 | 一覧表示 | 作成フォーム | 作成 | 個別表示 | 編集フォーム | 個別更新 | 個別削除 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| **HTTPリクエスト** | **GET** | **GET** | **POST** | **GET** | **GET** | **PATCH/PUT** | **DELETE** |
| **対応アクション** | **index** | **new** | **create** | **show** | **edit** | **update** | **destroy** |
| photos | /photos | /photos/new | /photos | /photos/:id | /photos/:id/edit | /photos/:id | /photos/:id |
| users | /users | /signup | /signup | /users/:id<br>/users/:id/following<br>/users/:id/followers | /users/:id/edit | /users/:id | /users/:id |
| sessions | - | /login | /login | - | - | - | /logout |
| account_activations | - | - | - | - | account_activations#edit | - | - |
| password_resets | - | /password_resets/new | /password_resets | - | /password_resets/:id/edit | /password_resets/:id | - |
| microposts | - | - | /microposts | - | - | - | /microposts/:id |
| relationships | - | - | /relationships | - | - | - | /relationships/:id |

# まとめ
最後は､良くわからない表になってしまったがなんとなくでしか分からなかったリソースの全体像がわかったと思う｡

なにより必要に応じて､**分かりやすいように名前付きルートの変更(users/newをsignup)をしている点**や**全てのアクションを使わなくてもリソースの考え方に則って実装することで､リソースとして扱うという実装方法の統一が図れるという点**､**14章で出てくるフォローの実装はさらにRESTのリソースをより活用した実装(ルーティングをネストさせている)という点**に気づけた｡

# 参考
[Representational State Transfer \- Wikipedia](https://ja.wikipedia.org/wiki/Representational_State_Transfer#%E5%8E%9F%E5%89%87)

[REST理論をわかりやすく。 \- Qiita](https://qiita.com/geshi/items/5275cc9d089105625c5f)

[ステートレスとは \- Qiita](https://qiita.com/mtakehara21/items/efcbbc3ba58a62c10eb6)

[ステートフル ステートレスとはどういうことか \- Sojiro’s Blog](http://blog.sojiro.me/blog/2014/09/13/stateful-and-stateless/)

[yohei\-y:weblog: ステートレスとは何か](http://yohei-y.blogspot.com/2007/10/blog-post.html)

[Hypertext Transfer Protocol \- Wikipedia](https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol)

[Representational State Transfer \(REST\)](https://www.f5.com/ja_jp/services/resources/glossary/representational-state-transfer-rest)

[RESTful Webサービスの概要](https://docs.oracle.com/cd/E28613_01/web.1211/b65960/overview.htm)

[Webの成功理由は制約 ８つしかないHTTPメソッド](http://kaihooo.com/http-method/)

[Webのアーキテクチャスタイル（設計思想） REST](http://kaihooo.com/rest/)

[RESTとは \- Blank?=False](http://stonebeach-dakar.hatenablog.com/entry/2016/06/25/131001)

[RESTfulって・・・？調べたメモ \| めもめも](https://iwjp.net/blog/2018/10/19/restful_memo/)

[「Webを支える技術」を読みました とRESTのまとめ \- 大学生からの Web 開発](http://karur4n.hatenablog.com/entry/read-webtechbook)

[URLとURIは何が違うの？ どちらが正しい呼び方？ \| 初代編集長ブログ―安田英久 \| Web担当者Forum](https://webtan.impress.co.jp/e/2010/03/09/7539)

[RESTful\-APIのURL設計を考えてみる \- Qiita](https://qiita.com/ak-ymst/items/344fc726e77115da3616)

[Railsのルーティングを極める\(前編\)](https://techracho.bpsinc.jp/baba/2014_02_17/15665)

[Web API（REST API）のURL設計 ｜ DevelopersIO](https://dev.classmethod.jp/etc/web-api_rest-api_url-design/)

[REST APIとは？ \- API設計のポイント](http://wp.tech-style.info/archives/683#toc8)

[翻訳: WebAPI 設計のベストプラクティス \- Qiita](https://qiita.com/mserizawa/items/b833e407d89abd21ee72)