Mojaviの呪縛
昨日のSkypeミーティングで、Actionフィルターでbefore/afterメソッドを呼ぶようにするかという議論の際に以下のような指摘がでた。
- Actionフィルターは最後に追加されるという特別扱いは今となっては違和感がある
- 現在エラーがあったらexecuteをスキップするということが固定になっているが、これも場合によっては逆の動きもできるという柔軟性があってもいいのではないか?
- このあたりの動きをまずは整理した後、どうするかを考えてもいいのでは?
Actionフィルターを最後に追加するというものはMojaviからいただいたアイディアだが、それを特別扱いする必要性はないどころか、それによる弊害もでてきているのかなと。
また、Actionフィルターで複数のことを処理しているからActionフィルターを改造してbefore/afterを呼ぶようにしようという発想になったのであって、もっと細分化されていればexecute()を呼ぶ前に普通にFilterでフックできたはずである。
ということで、Mapleがいろいろアイディアを拝借しているWebWork2をみてみると、以下のようなInterceptorが存在する。
Interceptor名 | 機能 |
---|---|
static-params | Actionに対して設定ファイルで指定した値をセットする |
params | Actionに対してリクエストパラメータをセットする |
component | Actionに対してコンポーネントをセットする |
workflow | Validationに失敗した場合、Actionを実行せずにINPUTのビューに遷移する |
prepare | Actionのprepareメソッドを実行する |
上記のように現在Actionフィルターがまとめてやっている処理が細分化されている。確かにここまで細分化されていれば、executeの前にフックを入れるとか、リクエストパラメータとコンポーネントをセットする順番を制御できる。
ここまで細分化すると毎回指定するのが大変だろうということになるが、Webwork2では複数のInterceptorの実行順をあらかじめ規定したInterceptorStackというのを定義できる。つまり、「static-parmas⇒params⇒component⇒prepare⇒workflow」というInterceptorStackを定義しておいて、それをInterceptorとして使えば、指定も楽になるという形だ。
ならばということで、Mapleでも現在のActionフィルターを以下のように細分化し、Actionフィルターが最後に呼ばれるという特例もはずすということにしてはどうかと考えている(フィルター名は仮です)。
Filter名 | 機能 |
---|---|
Filter_StaticParams | Actionに固定値をInjectionする |
Filter_Params | ActionにリクエストパラメータをInjectionする |
Filter_Component | ActionにComponentをInjectionする |
Filter_Action | Actionのexecuteメソッドを実行し、responseにview_typeを設定 |
Filter_BeforeAction | Actionのbeforeメソッドを実行する |
Filter_AfterAction | Actionのafterメソッドを実行する |
新しいActionフィルターでは、以下のような指定ができるようにするといいのではないだろうか。デフォルトの動作を「onError = skip」としてエラーが既に発生していればexecuteを実行せずに、「onError = execute」とするとエラー発生時にもexecuteを実行できるという形となる。同じようにbefore/afterも作っておけば、エラー時の動作を制御できる。
[Action] onError = execute
ここまで細分化されたら指定が大変だという点に関しては、WebWork2のInterceptorStackのような解決策ではなくて、maple.iniの継承機能で対処でいいかなと。
※知っている人は知っている継承機能ですが、Mapleでは上位の階層のmaple.iniを引き継ぐという機能があります。例えば foo_bar というActionの場合、webapp/modules/foo/bar/maple.ini が使用されますが、webapp/modules/foo/maple.iniが存在した場合その設定を先に使用します。これはどんどん上の階層をみますので最終的にwebapp/modules/maple.iniを定義しておけば全てのActionに共通のFilterをかけることができます。
という風に考えたのですが、どうでしょうか?どちらにしろ大きな動作変更になるので、3.2ではなくて、3.5での変更ですかね。