Scala LiftのView Firstの思想に刺激され紹介記事を書き、実際に使ってみてたどり着いたのは、これはちょっと使えないなという悲しい結末・・・とはあの頃予想できただろうか(いや、できない)。
正月とこれまで幾日かの土日を費やしたどり着いた結論は以下の通りだ。
結論
UIから作るViewFirstで開発を行いたい!場合、Angular.jsやKnockout.jsのようなフレームワークを導入し画面側から開発を行い、Model設計(JavaScriptクラス)が固まってきたらサーバーサイドで永続化の処理を実装するのがベストだ。
ロジック混入を回避する場合はAngular.jsならDirective、Knockout.jsでも普通にtemplateを使えば隠蔽可能だ(モジュール化をきちんとやるならAngular.jsの方がカスタマイズ性は高い)。
JavaScriptフレームワークの登場により、アプリケーションの画面動作はhtmlとJavaScriptでほぼ書けるようになってきている。WebComponentsなども登場しリッチな画面を簡単に作れるようになってきたこの状況では、サーバーサイド側からDOMを出力する(悪く言えば介入する)ViewFirstのフレームワークは逆に足枷になってしまうだろう。
特にLiftに関していえば、学習コストが高く情報が少ないのもデメリットとして上げられる。だから悪い、というわけではないのだが仕事(チーム)で開発するならこの壁は厚い。
Scalaでやりたい、というこだわりがなくMicrosoftに敵意がないのであれば、ViewFirstのフレームワークとしてはASP.NET WebFormの方が完成されているので使いたい場合こちらの方がお勧めできる。
もちろん今後Liftが進化を遂げクライアントサイドのフレームワークと連携をうまく取れる日が来るのかもしれない。ただ、その時まで、Liftは心の中にしまっておこう・・・と思う。
具体的な難点
色々(本当にいろいろ)あるが、一番はsnippet間の連携が取れない点だ。
ViewFirstなのだから、画面をsnippetで分割してそれらの間で連携をとりながら更新できる・・・のかと思いきやそうではないのだ。
これはある意味しかたがないことで、Webでは1Requestに対し1Responseなのだから「Aというsnippetを更新したらBも連動して更新する」というのは通常できない(例えば、投稿をポストしたらヘッダ領域の投稿件数を更新する、みたいな)。
そういう意味では、この点がサーバーサイドでViewFirstが実現できない最大の理由かもしれない。1Request(1event)に対しマルチレスポンスを返したいなら今のところクライアントサイドでやるしかないのだ。
ただ、Liftではサーバーサイドからのプッシュが可能なCometがサポートされているため、頑張れば上記のような実装も不可能ではない。
ただ、それを実装するということはクライアント/サーバー間をすべてAjax/Cometで制御するということだし、なによりCometで配信したら接続中の全クライアントに配信されてしまうので1:1の制御が必要になる・・・がこの機構がLiftにはない。
この点を突き詰めるなら、socket.ioやSignalRといったWebsocketの仕組みとクライアント側フレームワークをうまく組み合わせ、クライアントサイドの変更はJavaScriptフレームワーク、サーバーでの処理が必要なものはsocket.io/SignalRで送信し他クライアントに配信する、という方がいいだろう(これは面白い・・・かもしれない)。
別の解として全画面を親となる一つのsnippetで囲んでしまうという手もある。これなら全画面Post->全画面返却なので好きな部分を複数更新できる。
で、実はこの思想を実現しているのがASP.NET WebFormなのである。私はこれをやった時なんで全画面をわざわざ送っているのか理解できなかったが、くしくもLiftに触れることでその理由を悟った。。。
ASP.NET WebForm はMicrosoftらしくVisual Studioのサポートもあいまってかなり簡単に開発できるし情報もLiftからすると相当多い。もちろんLiftではjQueryライクなセレクタがあるため書きやすいと言えば書きやすいが、そうするともはやサーバーサイドでjQueryを書いているのと変わらなくなってきて、それならわざわざサーバーでやらんでも・・・という話になってしまう。
そんなわけで、リアルでの更新を突き詰めるならsocket.io/SignalR、サーバーサイドでやっていくならASP.NET WebFormかな・・・となってしまうのである。