岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

フレームワーク作りの一歩はRouterから

RubyでオレオレWebアプリケーションフレームワークを作ろう」と思ってからどれほど経ったのか、過去記事をさかのぼれば分かりそうですが、きっと呆れるくらい経っているので、あえて調べないことにした岩本です、こんばんは。

フレームワーク作りにこれだけ時間がかかっているのは「フルスタックにしなければならない」という固定観念があったせいだと、最近ようやく気づきました。id:dannさんによる「Angelosで学ぶ優しいWAFの作り方」のおかげです。

フレームワーク作りはそんなに大変じゃない

dannさんのプレゼンテーションでは、フレームワークの最小構成要素が下記のように示されています。

  • Engine - req/res, サーバー抽象化
  • Dispatcher - URLとControllerのmapping
  • Component Loader - controllerのload + controller検索

言い換えると、たったこれだけの仕組みを作れば、フレームワークのできあがりというわけです。

Rubyには、Rackという素晴らしいEngineがあるので、これを使わない手はありません。つまり、実質的に自前で用意すべきは、DispatcherとComponent Loaderの2つだけということになります。はい、俄然やる気が出てきました。

フレームワークの最小構成要素はRouterとDispatcher

ここからは私独自の考えになるのかもしれませんが、DispatcherとComponent Loaderの責務を単純化して考えると:

  1. Rackから渡されるenvを解析し、処理を委譲すべきコントローラとアクションを決定する
  2. コントローラのインスタンスを生成し、アクションを実行する

となります。PHPZend Frameworkでは、前者をRouter、後者をDispatcherと呼んでいます。

これらを区別せずに、ただRouterと呼んだりDispatcherと呼んだりすることもあるようですが、区別したほうがフレームワークユーザの理解を助けるのではないかと私は思っています。

なお、Component Loaderは、Dispatcherが依存する内部ライブラリというイメージです、今のところ。

Routerインターフェースの決定版を定義したい

以前作ったRuptaは、DispatcherではなくてRouterです。「あとはDispatcherさえ作れば、フレームワーク完成」といいたいところですが、Ruptaへの不満がいろいろ募ってきたので、また別のRouterを作ろうと考えています。

新しいRouterの詳細は後日の日記に譲りますが、いま漠然と浮かんでいるのは「RouterやDispatcherもプラガブルにしたい」という野望です。プラガブルにするには、Routerのインターフェースを決めなければなりません。Rackのような抽象化をRouterレベルでトライしてみたいということですが、どうなりますやら。