HTML5時代の「運営しやすいアーキテクチャ」の話
2009.10.08
増井君と二人でPhotoShareというサービスを立ち上げてもう15ヶ月になるが、いろいろと学んだことがある。その中でもつくづく思うのは、サービスを作り上げる段階よりも、運営のことを考えた設計が大切なこと。つまり、メンテナンスしやすい、テストしやすい、多少のミスをしても大丈夫、こまめなアップデートがしやすい、作業分担がしやすい、などなどである。
そんななかで強く感じるのは、「AJAXを見た目や使いやすさの面だけに利用するだけでなく、『運営しやすいサービス』を作るのに利用できないか」ということである。
私のイメージするアーキテクチャを図にするとこんな感じになる。
まず一番の特徴は、テンプレート等を利用したHTMLのダイナミックな生成をすべてやめて、データ(JSONもしくはXML)だけをダイナミックに生成するようにし、HTMLはスタティック・ファイルをサーバー側に置いておく(上の図で、CSS, HTML, JS, Media Filesはすべてスタティック・ファイル)。
この設計の一番目の利点は、「(Controllerとブラウザーの間の)Web Service APIの定義をきちんとしなければならなくなる」点である。「そんなことはどんなアーキテクチャでも可能だ」と感じる人も多いだろうが、納期に迫られたり緊急のバグフィックスを施す時に、どうしても人間は安易な方向に走ってしまうもの。そんな時に本来Controller側に置くべきものがViewに紛れ込んでしまったり、仕様書に書かれていないViewとController依存関係が生まれてしまったり、というのは良くある話だ。HTMLをスタティックファイルにし、JavaScriptでJSONなりXMLを引っ張って来て表示する設計にしておけば、さすがにそこの仕様定義をおろそかにはできない。すごく人間的な話だが、こんなつまらないことが「運営しやすいサービス作り」には大切だと思う。
もう一つの利点は、点線で囲まれた「アプリケーション・ロジック」の部分のデプロイメントと、HTMLやCSSなどのアップデートを別のサイクルで行える点である。PhotoShareを運営していてつくづく思うのは、ユーザーの声を聞き入れてもっと頻繁にウェブサイトのUIを変更したいな、ということである。アプリケーションロジックと表示側をAPIできれいに分けておけば、細かなUIの変更を比較的少ないリスクで行うことが可能になる。UIをちょっと変更するたびにアプリケーション・ロジックをすべてデプロイしていては手間もかかるしリスクも高い。
次に大切だと思うのは、(図ではちゃんと表現できていないが)ModelとControllerの役割を少し見直すべき、という点である。PhotoShareは主にRailsで作られているので、ModelはActiveRecordが担当しているわけだが、Modelのレイヤーが非常に薄いために(O/Rマッピングをしているだけ)、データベースの整合性の責任がController側にある。そのため、ちょっとした機能変更のたびにAPIレベルでのテストを大量に走らせなければならないし、それでもどうしてもミスが生じてしまう。
そこでデータベースの整合性の責任を100%Modelに負わせ(つまりModelを単なるO/Rマッパーではなく、ビジネスロジックを含んだモジュールとして設計して作り込む)、そこだけは徹底的なテストケースを作って強固なものにしておくことにより、Controller側の変更で多少のミスをしてもデータベースの整合性が壊れたりしない、という設計にしておくとController側の変更がもう少し気楽に、かつ頻繁にできると考えている。
こうは書いてみたが、実際にサービスとして運営するとなると、AJAXが使えないブラウザーはどうするという問題や、顧客のために受託でものを作っているからアップデートのたびに仕事が取れるアーキテクチャの方が良い、などの大人の事情があったりするのですぐに実践できる話ではないかも知れないが、HTML5の目指している方向は明らかにこちらだ、と思う今日この頃である。
Ajaxを使う上でのもう一つの障壁が、検索に引っかからない事だと思います。
あと、すみません、ActiveRecord自体はModelにロジックを含むのですが、コントローラのバグが問題になるのは、私がcontroller側にモデルロジックを入れてしまったりしている為です。
Posted by: masuidrive | 2009.10.08 at 23:33
Modelにビジネスロジック全てを押し付けると責任が大きくなり過ぎるように思えます。
そこで、ModelとControllerの間にもう一つレイヤーを置いてみてはいかがでしょうか。
私の場合、このレイヤーに Web Service API の実装を任せてControllerはあくまでフロー制御だけに留めています。
Posted by: ishikawash | 2009.10.09 at 03:35
このアーキテクチャにかなり賛成です。
Modelが中心にあってその表現としてXMLや、DBデータがあるイメージを持っています。
開発するときは完全にブラウザサイド/サーバサイドで責任を分離できるのでXMLのAPI定義を厳密にするメリットが十分ありますし、バグがあった時のの問題解決が早いです。
Posted by: shat | 2009.10.09 at 08:40
いわゆるリッチクライアントの形ですね。
AJAX使えないブラウザ向けや検索サーバ対策には、このシステムをWebサービスとして使うAPI-HTML変換サーバ(?)を別に用意するのが良いでしょう。
(そもそもこの形は、別のサービスからも容易に使えたり非Webブラウザのクライアントアプリから使えたり、と利用形態やユーザへのリーチ手段を広げられるところから始まっていますし。)
Posted by: ねどぬい | 2009.10.09 at 22:24
J2EEとかでもさんざ議論されてることの様な気がします。
層ごとに別々に触れる様になるのは魅力ですが、
逆に言うと、
両方触らないといけなくなる欠点が有るのは自明ですよね。
アジャイルにやろうとするとどうしても一層ばかり触ってしまう。
どっちを取るか…に成ってしまうので、両立出来る手法が有ると良いんですけどね。
Posted by: ryu | 2009.10.11 at 20:11