部分一致ルートに関する考察
現在のルーターの仕様は、ルートをハッシュ配列に入れて、順に一致をチェックしながら決定する仕組み。あらゆるルートは検索を開始する前に登録するのが基本。URLのassemble時に名前指定でルートを特定してURLに変換するため、名前付きで登録されていないルートでは処理できない。
しかし、サイト内のルーティングのカスタマイズ要件が複雑になると、すべてのルートを登録するのは現実的ではなくなる可能性がある。URLを育成する際も名前を認識しなければならないが、すべてのモジュールがグローバルなルート名を認識しなければならないとすると、管理に一工夫必要になる。
部分一致ルート
最初に一致させるルートは少なくしておき、一致したルートからさらに詳細化するという考え方もありうる。ディレクトリ探索に似ている。段階的ルーティングは、多数のユーザーを抱えて、各ユーザーがURLルーティングを決定しうるような大量のルーティングを発生させてしまうサービスでは重要になる。
ルートのチェーン
Zend_Controller_Router_Route_Chainを使うと、ルート仕様をチェーンした新しいルートを作成することができる。現在のZend_Controller_Router_Route_Chainの仕様はチェーンしたルートのすべてでmatchした場合に、そのチェーンにマッチしたという判定になる。完全一致ルールなのでhostname一致の後にpathで一致させるぐらいの使い方になる。
このChainのmatchには未使用のpartialという引数がある。これは、部分一致を使った再帰検索への布石か?と邪推してみる。MLのログかWikiを見ればどっかに書いてあるのかもしれませんが・・・
再帰ルートが実現されていない理由(?)
ルートがmatchしたらその子ルートにマッチするかを検索するという再帰ルートを作成する場合、ルーター(通常はRouter_Rewrite)には大元のルート名しか登録されない。したがって、assemble時に下位のルートを名前指定で到達することができない。再帰ルート用のassemble方法を用意する必要がある。
パラメーターに埋めて解決?
ルート名は大まかな第1段階の分類とし、内部ルート名をパラメーターとして持って置く方法で解決できるかもしれない。
セクション内のルートについては、パラメーター内に、セクション内ルート名みたいにパラメーターをつけてあげれば名前解決時にパラメーターとして与えていくことはできるだろう。
もう一つは、ルーターを少しだけ改造し、名前解決ルールに再帰ルートを意識した名前付けルールを適用させる方法もある。ルートを解決するりゾルバを最初に組み込ませるようにすれば、名前付けルールは自由になる。(が、その分処理が重くなるわけで、特殊な用途の時しか使わないだろうけど)
部分一致ルーター(仮称)の仕様
- 自分に登録されたルート一覧を順に検索。(原則的にパスを与える =>つまりVersion1対応)
- 一致したら、値を受け取ってスタックし、一致した部分のパスを切り落として、新しいパスを作って次のイテレーションに回す
セクションルート(仮称)の仕様
部分一致ルートについて考えると、たとえば、それをセクションとしてモジュールにmatchさせるルートと規定し、その次に、残りのコントローラーとアクションを決定するルートをセクションルートに登録するものとする。
- 大元のルーターには基本的にセクションレベルまでのルートを登録
- セクションルートにmatch
- セクションの内部ルーティング情報をロード
- matchの残存パスに内部ルートがマッチするか順次チェック
- 最初にマッチしたルートを正規ルートとして採用
- どのルートにもマッチしなかった場合はそのモジュール内のデフォルトコントローラーにマップさせる。
- 階層化されたルートについては、名前付けルールをコントローラーに準拠して、foo_fugaのように_で区切り、内部ルートであることを示すようにする。
- ルーターを拡張して、名前を判定している部分で、最初の_の左側だけを名前として扱い、assembleを伝播させる。
- 受け取った側のセクションルーターは名前から必要なルートを読み込んでルートを決定する。
ルートの遅延ロードについては、コンフィグを保存したパスだけを登録しておき、matchやassembleをコールされた時に、コンフィグパスが残っていれば読み込んで追加するといった使い方になるかもしれない。