次世代Webフレームワークの設計思想~RESTful Webサービス
「RESTful Webサービス」本を買ってみた。
まだ読んでないけれど、この本を買った動機を振り返ってみる。
【1】Webフレームワークの歴史とその限界
Webアプリは最初はオモチャみたいなものだった。
普通は、掲示板のようなアプリをPerlでCGIを書いて作っていただろう。
そして次第に、ViewからControllerを分離する設計をするようになった。
Javaの場合、JSP+Servletという仕組み。
だが、システムが巨大化していくうちに、Webフレームワークが必要とされるようになってきた。
そのWebフレームワークの基本思想として、MVC2モデルが叫ばれるようになった。
MVC2モデルは、GUIアプリのMVCモデルのWeb版といっていい。
この思想によって、大概のWebフレームワークは、MVC2モデルを標榜するようになった。
そして、Javaはこの思想を突き詰めて、Model部分にEJBを作り出した。
EJBは、永続化装置とネットワーク分散型装置の2つを実装した巨大なビジネスオブジェクト。
EJBはステートフルなBeanとステートレスなBeanの2種類があるが、皆、ステートレスセッションBeanばかり使う。
理由は、ステートフルな方が本当は使いやすいが、ネットワーク越しにステートフルな状態を持つのは遅いから。
確かに最新技術をふんだんに取り入れて魅惑的だが、何しろ重くて実用的にならない。
更に、その頃は、SOAPという概念も出てきた。
SOAPは、Webというネットワーク上でメソッドコールできるようにすること。
つまり、ネットワーク越しのRPC。
でもすごく遅い。
2000年当時は、ネットワーク越しにメソッドコールで1分以上もかかる。
とても使い物にならなかった。
そして、今でもSOAPやEJBは、Webアプリ開発の主流となりえていない。
【2】プログラマにとってステートフル、ユーザにとってステートレスなWebフレームワークとはどんなものか?
Webフレームワークとは大まかに下記の流れと言えるだろう。
HTTPリクエストからデータをもらう
↓
プログラムはそのデータを使ってゴニョゴニョ処理する。
RDBへ放り込んだり、ファイルをアップロードしたり。
↓
プログラムが作ったデータをHTTPレスポンスに渡す
↓
Viewを表示する
画面の状態を保存するには、セッションやクッキーを使うしかない。
クレジットカード番号や個人情報はViewでHiddenで保持するのは危険。
でもセッションの状態管理は難しい。
画面遷移が複雑になるほど、セッションはどんどん汚れていく。
Webアプリの鬼門はいつも「戻るボタン」と「注文ボタンの2度押し」。
例えば、戻るためには、どの画面から飛んできたかを知らないといけない。
前の画面に戻るパターンは、実は、その2個前の画面の状態に依存する例もある。
あるいは、会員登録フローならば、新規会員登録なのか会員情報修正なのかで、戻る場所は違う。
画面遷移を制御するためのフラグをリクエスト変数に追加していくうちに、スパゲティコードになる。
他に、最終注文画面の注文ボタンを2回誤って押したら、同じ商品が2度注文されてしまう。
普通はそんな誤動作を防止するために、注文処理後すぐにセッションをクリアしたり、注文ボタンを押した時刻をHiddenで保持したり、あるいはトランザクション・トークンキーを使ったりする。
どの方法にせよ、たかが2度押し防止のために、かなり面倒な実装をしなければならない。
「境界を越える: 継続とWeb開発、そしてJavaプログラミング」では、そんな疑問に一つの回答を示している。
合言葉は「プログラマーにとってはステートフル、ユーザーにとってはステートレス」。
つまり、画面の状態を保持する機構がプログラマにとって必要。
だが、スケーラビリティやユーザビリティを考えると、ユーザにとってステートレスの方が圧倒的に使いやすい。
この矛盾した設計を最初に実現したのは、実はLispのWebフレームワークだと言う。
Paul Grahamが「ハッカーと画家」の中で、既に1995年のViaWebにおいて、この基礎となっている手法を使ったらしい。
この手法は、『継続(continuation)』というプログラミング制御構造を使うことに意義がある。
この基本的な考え方は、「プログラミング・フレームワークが、アプリケーションの状態をリクエストの前にロードし、また各リクエストの後に保存するようにする」ということ。
GausheというSchemeで作られたKauhaというWebフレームワークでもこの考え方が使われているらしい。
Rubyにも、『継続(continuation)』というライブラリがある。
基本は同じ。
でも、デバッグするとどのステートメントをたどるか分からないのが普通で使いづらいのが普通。
Ruby関西では、yharaさんが講演してくれたのが分かりやすかった。
そこで問題。
『継続(continuation)』を使った場合、画面の状態はどこに保存されるのか?
それは実は、URLに隠れている。HTTPメッセージへ全ての情報(リソース)を渡すのだ。
ここからRESTの話に移る。
【3】RESTの定義とは?そしてRESTを実現したRuby on Rails
WikipediaのRESTの解説が非常に分かりやすい。
HTTPプロトコルについてもう一度おさらいしてみよう。
似たようなプロトコルにFTPがある。
こちらの方がHTTPよりも原始的だが。
FTPでファイルをアップする時、WindowsユーザならFFTPアプリを使うだろうが、ftpコマンドを使って、コマンドラインでもアップできる。
同様に、HTTPプロトコルでも、GETやPOSTコマンドを使って、直接HTTPサーバーに問い合わせることができる。
大まかには、RESTとは、このコマンドを拡張して制限したアイデアを指す。
RESTとは、下記の設計原則を持つと言われている。
◆ステートレスなクライアント/サーバープロトコル
HTTPメッセージの一つ一つが、そのリクエスト (メッセージ) を理解するために必要な全ての情報を含む。
◆すべての情報 (リソース) に適用できる「よく定義された操作」のセット
HTTP では操作 (メソッド) の小さな集合で定義されている。
つまり、"GET"、"POST"、"PUT"、"DELETE"。
これらはデータ永続化に要求される CRUD の概念に似ている。
◆リソースを一意に識別する「汎用的な構文」
すべてのリソースは URI (Uniform Resource Identifier) で表される一意的な (ユニークな) アドレスを持つ。
それは大概、訳の分からないトークンキーかセッションキーのような形式になる。
◆アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
多くの場合、HTMLかXMLに情報およびその他のリソースへのリンクを含める。
これによって、リンクを辿るだけで、必要な情報を参照できる。
状態を逐一保持する必要はない。
これらの設計思想は、SOAPやEJBなどの思想と明らかに異なる。
むしろ、よりシンプルに考えたものだ。
そして、この設計思想を最初に実現したのが、Ruby on Railsだと思う。
少なくともRubyKaigi2006のDHHの講演を読むと、彼がREST実装を強く意識しているのが読み取れる。
更に、最新のRails2.0では、RESTサポートが強化され、セキュリティも改善されていると言う。
Ruby on Railsの凄さは、下記4点に集約されると思う。
・フルスタックなWebフレームワーク
・CoCというシンプルな設計思想
・RJBを使うと、Ajaxと親和性が高い
・RestfulなWebフレームワーク
最後のRestfulという概念は、Ruby on Railsを離れて、もっと抽象化できるはず。
そんな内容が書かれていると思うので「RESTful Webサービス」を読んでみようと思う。
| 固定リンク
「プログラミング」カテゴリの記事
- Javaのモジュールシステムの考え方をまとめてみた(2022.10.21)
- Javaのモジュールシステムは複雑性をより増している(2022.09.10)
- Javaはなぜ関数型言語になろうとしているのか(2022.09.02)
- Javaのラムダ式の考え方(2022.08.10)
- Javaはオブジェクト指向言語ではなく関数型言語だった~「[増補改訂]関数プログラミング実践入門」はお勧めの本だ(2022.08.06)
コメント