Ruby on Rails関連のサイトを見てると「RESTfulな〜」という表現をよく見かけるので、調べてみたメモです。
RESTfulとは?
最初に、RESTfulが形容詞で、名詞形にするとRESTです。
で、Wikipediaを読むと、RESTとは、Webの仕組みを利用してWebサービスを提供できるようにするための設計思想(制約)の集まり、を指すそうです。
って読んだだけで「お、おぅ」となりますが、要は厳密に「こういうもの」といった仕様のようなものはなく、Web(HTTPプロトコル?)を利用したクライアント/サーバ型のシステムで「こうすると良いんじゃないの」という設計の考え方を指すようです。
なかでも大きく下記の4点がポイントで、この原則に従って作成されたシステムやAPIのことを”RESTfulなシステム”、とか”RESTfulなAPI”と呼ぶようです。
-
- ステートレスなクライアント/サーバプロトコル
後述しますが、システムの状態とかセッションなどに依存しないことが期待されるようです。 - すべての情報(リソース)に適用できる「よく定義された操作」のセット
要はHTTPのリクエストメソッドを使う、ということのようです。 - リソースを一意に識別する「汎用的な構文」
同じURLに同じパラメータを渡せば、常に同じ結果が返ってくることが期待される、って感じですかね。また、URLに実装依存の情報を含めないことが期待されるようです。(login.jspは、loginだけでアクセス可能にするとか) - アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
ハイパーメディア=HTMLのリンク、というイメージで良さそうです。
- ステートレスなクライアント/サーバプロトコル
なお、考え方として、HTTPのリクエストメソッドとURLが「動作」と「モノ」の関係になるのが望ましいようです。
(URLはできるだけ名詞になるよう設計すべき・・・?)
ステートレスって・・・?
リクエストのたびに必要な情報を全て含めて送信するような自己完結型であることを指します。これにより、サーバの資源をすぐに開放できるので、負荷の増大に応じて性能を向上させやすくなります。
そもそも、HTTP自体がステートレスなプロトコルであり、ステートフルにするためユーザの要求を追跡する情報(セッションやCokkieなど)をアプリケーション側で保持するようにしていますね。
対して、ユーザと対話する形でやり取りをするFTPなどがステートフルなプロトコルになります。
分かりやすい例えがあったのでリンクだけ。こんな感じでステートレスにしておけば、お店(システム)が混んできても店員(サーバ)を増やせば良いよね、ということかと。
RESTfulにすると何が良いの?
ステートレスになるので、将来的なシステム規模の拡大(や縮小も?)をしやすくなります。
また、既にあるWebの仕組み(HTMLとかJSONなど)を使うので、他システムとの連携がしやすくなります。
あとはインターフェースを固定できるので、環境を変えたりする場合に互換性の問題が発生しづらくなります。(例えば、RESTfulなシステムではURLにservletとかcgiとかを含まないので、cgiからservletに変更してもURLは変わらない→利用者から見ればインターフェースが変わらない、ってことにですかね)
Webの仕組みについて
Webの仕組みとしてよくあるのは、クライアント(Webブラウザ)からサーバにリクエストをして、その処理結果をサーバがクライアントに返す、というピンポン形式での情報やり取りです。
その中で重要になってくるのが、URLとリクエストメソッド、ステータスコードの3つです。
クライアントからURL(どこへ・何を)の情報とリクエストメソッド(どうする)の情報を送信すれば、サーバからステータスコード(どうなった)として結果が返ってくるイメージです。
URL(どこへ・なにを)
リクエストの送信先を示すアドレスです。http://example.com/users/new とか。
見慣れた形式なので何となくイメージはしやすいかな、と。
リクエストメソッド(どうする)
クライアントから送信するリクエストの種類を示す情報で、基本的に下記4つになります。
- GET ……. 取得
- POST …… 作成
- PUT …… 更新
- DELETE …. 削除
データの作成(Create)、取得(Read)、更新(Update)、削除(Delete)の頭文字を取って「CRUD」とも呼ぶそうです。
ステータスコード(どうなった)
リクエストに対する処理結果を伝えるためのもので、成功・失敗(とその理由)を3桁の数字で表します。
- 200台 … 成功
- 300台 … リダイレクト
- 400台 … 失敗(クライアント側の原因によるもの)
- 500台 … 失敗(サーバ側の原因によるもの)
よく見かけるのは、URLを打ち間違えた場合に遭遇する「404 Not Found」とかサーバ側でエラーになった場合の「500 Internal Server Error」とかでしょうか。
これらを活用することでRESTな設計を目指す、ということのようです。
・・・で、具体的にどうすれば?
何となく考え方は分かったけど、具体的にどうすれば?というところですが、今のところ成功しているRESTfulな仕組み(フレームワーク)がRailsということのようです。
ここからRailsで言うところのルールをザクッとメモです。
Railsでは、Webアプリに必要となる基本的な7つのアクション(index,new,create,show,edit,update,destroy)を用意しています。
Ruby on Railsでアプリを作成する際は、config/routes.rbファイルによってルーティングを設定することになりますが、下記1行を書くだけでusersコントローラに対して上記7アクションのルーティングが自動的に設定されます。(あとで出ますが、コントローラによって不要アクションは省略も可能です)
resources :users |
routes.rbファイルに記述したら、ルーティングを確認するために rails routesコマンドを実行します。すると、以下のようなルーティング情報が表示されます。1行でこんなに色々生成してくれるのはスゴいな、と。
Prefix Verb URI Pattern Controller#Action users GET /users(.:format) users#index ... ユーザ一覧の取得 POST /users(.:format) users#create ... ユーザ登録 new_user GET /users/new(.:format) users#new ...... ユーザ登録画面の取得 edit_user GET /users/:id/edit(.:format) users#edit ..... 特定ユーザ編集画面の取得 user GET /users/:id(.:format) users#show ..... 特定ユーザ情報の取得 PATCH /users/:id(.:format) users#update ... 特定ユーザ情報の更新 PUT /users/:id(.:format) users#update ... 同上 DELETE /users/:id(.:format) users#destroy... 特定ユーザ情報の削除
(*) PUTは旧バージョンで使われていて、現在はPATCHを使うのが一般的のようです。
ここまでで、そーいえばWebアプリでよくある「ログイン」が無いんだけど?と思ったのですが、ログインについても以下のように7つのアクションを割り当てて作成するようです。resoucesとして記述すると不要なルーティングまで作成されてしまうので、必要な下記3つだけを個別に記載する方法をとります。
- new ……. ログイン画面
- create …. ログイン処理(=セッションの作成)
- destroy … ログアウト処理(=セッションの削除)
こんな感じで、あらゆる処理を上記7つのアクションにあてはめたりとRails流に従って作成することで、余計なコードを書かずに効率的なコーディングを実現できる、ということのようです。(Railsルールに従って書けば、Railsがよしなに色々としてくれる)
まとめ
RESTについては、あくまで「考え方」なので、原理主義的に必ずこうしなければならない!というものではなさそうです。
まあ、作成するシステムに合わせて臨機応変に、ということでしょうか。
コメント