Blank?=False

「呉下の阿蒙にあらず」をモットーにしたITエンジニアの日々

RESTとは

f:id:stonebeach-dakar:20160618082625p:plain

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の機能を使ってデータのやり取りをしよう、というのが基本的な考え方になっています。

他のアーキテクチャには、xmljsonを使ってデータのやり取りを行う物もあります。


すべてのリソースは、ユニークなアドレスがあり、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ではreadshowdeletedestroyに置き換えられます。
例えば、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つ存在します。
neweditはHttpメソッドがGETにとなっていて、実際にサーバーに送信するためのURIではなく、 new,editページを表示するためのURIなのです。

例えば、ユーザーを新規作成するときに、

  1. newアクションを呼び出してから新規作成ページを取得
  2. フォームに新しいユーザーのデータを入力後、OKボタンをクリックすることでcreateアクションを呼び出す
  3. createアクションでDBMSに新しいユーザーのデータを保存

という処理の流れにしてね、とRailsURIパターンを作ってくれるわけです。
updateが2つあるのは、Rails4.0以前は更新の時にPUTメソッドを使っていたのが、4.0以降はPATCHメソッドを使うようになり、旧バージョンとの後方互換性のために残されいる、というのが理由です。
そのため、今後、PUTは作成されなくなる可能性が高いと言われています。

あとがき

こういうアーキテクチャが実際にこうなって、フレームワークでこういうふうに動いている、というのを説明するのはかなり難しいと感じました。
まだまだこの記事はわかりにくいとおもいます。もっとわかり易く説明できるには、自分自身がちゃんとRESTを理解していく必要があると思いました。

参考文献・サイト

REST - Wikipedia

thinkit.co.jp

kaihooo.com

qiita.com