RESTとは
RubyOnRailsにおいて重要なキーワード、REST
。
Webシステムの基礎でもあるのですが、あまり良く理解してませんでした。
ちゃんと理解することでよりいい設計のシステムが作れるようになると思い、勉強しなおしてみました。
RESTとは?
Representational State Transfer
略してREST
。
Wikipedia先生によると
ウェブのような分散ハイパーメディアシステムのためのソフトウェアアーキテクチャのスタイルのひとつである。
分散ハイパーメディアシステム
、とは複数の小さいコンピュータ(サーバーマシン)で構成されるネットワークを用いて、テキストだけではなく画像、音楽、など様々なメディアが相互にリンクされたシステムです。
要はインターネットですね。
Webアプリケーションのアーキテクチャスタイルの1つ、と紹介されている通り、他にもSOAP
というアーキテクチャがあります。
WikipediaではRESTについての原則についてこう書かれています。
原則
REST を支持する人々は、ウェブのスケーラビリティと成長は、次に述べるような、いくつかのキーとなる設計原則の結果であると論じる。
ステートレスなクライアント/サーバプロトコル
HTTPメッセージの一つ一つが、そのリクエスト (メッセージ) を理解するために必要な全ての情報を含む。そのため、クライアントもサーバも、メッセージ間におけるセッションの状態を記憶しておく必要がない。ただし実際には、多くのHTTPベースのアプリケーションはクッキーやその他の仕掛けを使ってセッションの状態を管理している (URLリライティングのような一部のセッション管理手法を使うシステムは、RESTful ではない) 。
すべての情報 (リソース) に適用できる「よく定義された操作」のセット
HTTP では操作 (メソッド) の小さなセットが定義されている。最も重要なのは "GET"、"POST"、"PUT"、"DELETE" である。これらはデータ永続化に要求される CRUD と比較されることがある。もっとも "POST" に関しては CRUD にはぴったり対応していない。
リソースを一意に識別する「汎用的な構文」
RESTful なシステムでは、すべてのリソースは URI (Uniform Resource Identifier) で表される一意的な (ユニークな) アドレスを持つ。
アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
RESTシステムでは、多くの場合、HTML文書またはXML文書を使う。こうした文書に情報およびその他のリソースへのリンクを含める。こうすることにより、あるRESTリソースから他のRESTリソースを参照したい場合は単にリンクを辿るだけでよい。レジストリなどの他の基盤的な機能を使う必要はない。
わかりやすく要約すると、
- HTTPの機能を最大限使って情報をクライアントとサーバーでやり取りしよう
- すべてのリソースは、ユニークなアドレスがあり、GET,POST,PUT,DELETの機能をもつ
- HTMLのリンクをたどることで、ある情報のページから別のリソースのページに移動することができる
こういうふうにWebシステムを設計しましょう、というのがRESTの考え方です。
RailsにおけるREST
上の要約をRailsに当てはめて考えてみます。
HTMLのリンクをたどることで、ある情報のページから別のリソースのページに移動することができる
基本的なWebページの遷移なのでRailsに限った話ではないので、スルーします。
HTTPの機能を最大限使って情報をクライアントとサーバーでやり取りしよう
HTTPのリクエストには、様々な情報を格納することができるようになっています。
HTTPのメソッドによって格納できる情報が異なり、これらのHTTPの機能を使ってデータのやり取りをしよう、というのが基本的な考え方になっています。
他のアーキテクチャには、xml
やjson
を使ってデータのやり取りを行う物もあります。
すべてのリソースは、ユニークなアドレスがあり、GET,POST,PUT,DELETの機能を持つ
個人的に、RailsにおけるRESTはこの考え方だけわかってればだいたい理解できると思います。
リソースとは、RailsにおけるModel
に相当するもので、データ
というイメージになります。
GET,POST,PUT,DELETEは、HTTPの機能であり、データの操作は、CRUD
の4機能(Create
,Read
,Update
,Delete
)が基本になります。
(Create=作成, Raad=読み込み, Update=更新, Delete=削除)
GET,POST,PUT,DELETEは以下のようなパターンでCRUDの4機能に割り当てられます。
HTTP | CRUD |
---|---|
GET | Read |
POST | Create |
PUT | Update |
DELETE | Delete |
これらを踏まえて、要約をRails風に考えてみると、
- すべてのModelは、ユニークなアドレスがあり、作成・読み込み・更新・削除が行える
これがRailsにおけるREST
の基本的な考え方になります。
RailsでRESTに対応する
CRUDの4つの機能が、Railsにおけるコントローラの各アクション
になります。ただし、Railsではread
はshow
、delete
はdestroy
に置き換えられます。
例えば、User
というModelでHttpメソッドに対応するアクションとURIを考えると以下のようになります。
HTTP | CRUD | アクション名 | URI |
---|---|---|---|
GET | read | show | Users/show |
POST | create | create | Users/create |
PUT | update | update | Users/update |
DELETE | delete | destroy | Users/destroy |
このようなURIパターンを作ることで、HTTPの各メソッドに対応したCRUDの4つの機能を使う事ができるようになります。
つまり、RESTアーキテクチャに従ったWebシステムになります。
Railsでは、こういうパターンのURIを効率よく作成するために、resource
メソッドが用意されています。
routes.rb
ファイルで、resourceメソッドを使うと、
routes.rb
Rails.application.routes.draw do resource :user end
以下の様に各アクションに対応したルーティングをRailsが自動で作成してくれます。
$rake routes Prefix Verb URI Pattern Controller#Action user POST /user(.:format) users#create new_user GET /user/new(.:format) users#new edit_user GET /user/edit(.:format) users#edit GET /user(.:format) users#show PATCH /user(.:format) users#update PUT /user(.:format) users#update DELETE /user(.:format) users#destroy
実際に出力されたURIパターンは7個あり、上のパターンにはないnew
,edit
,そしてupdate
が2つ存在します。
new
とedit
はHttpメソッドがGET
にとなっていて、実際にサーバーに送信するためのURIではなく、
new
,edit
ページを表示するためのURIなのです。
例えば、ユーザーを新規作成するときに、
new
アクションを呼び出してから新規作成ページを取得- フォームに新しいユーザーのデータを入力後、OKボタンをクリックすることで
create
アクションを呼び出す create
アクションでDBMSに新しいユーザーのデータを保存
という処理の流れにしてね、とRailsがURIパターンを作ってくれるわけです。
update
が2つあるのは、Rails4.0以前は更新の時にPUT
メソッドを使っていたのが、4.0以降はPATCH
メソッドを使うようになり、旧バージョンとの後方互換性のために残されいる、というのが理由です。
そのため、今後、PUTは作成されなくなる可能性が高いと言われています。
あとがき
こういうアーキテクチャが実際にこうなって、フレームワークでこういうふうに動いている、というのを説明するのはかなり難しいと感じました。
まだまだこの記事はわかりにくいとおもいます。もっとわかり易く説明できるには、自分自身がちゃんとRESTを理解していく必要があると思いました。