はじめての Seaside - 異端の Web アプリケーションフレームワーク - 梅澤真史 <ume@softumeya.com>
Seaside のコンセプト 異端 であること 長年にわたって Web の世界では開発のためのベストプラクティスが蓄積されてきた 出来る限り状態を保持しない注意深く吟味された意味のある URL を使うモデルと表示を分離するためにテンプレートを用いる等である Seaside はこうしたルールを全て破った Web アプリケーションフレームワークだ Web 開発でこれまで叡智とされてきたことを放棄してみると何が得られるのか? 実に多くのことが 得られたのだ --Avi Bryant
Seaside の特徴 継続 による状態の保持 ステートフルな Web ユーザの実行段階ごとに状態を保持 URL は自動的に作られる REST と違うアプローチ 実行状態を維持するために存在 テンプレートの否定 ページではなくコンポーネントを意識 HTML はあくまでコード (Smalltalk) で生成 =>Web アプリ開発にオブジェクト指向を取り戻した
Seaside の MVC よく Web 系にみられる なんちゃって MVC ではない C が手続きの集合 V は表示テンプレート M はただのデータホルダ などというものが MVC と呼ばれているが... Seaside の MVC は GUI で見られる本来の MVC にきわめて近い VC 一体型の MVC( コンポーネントモデル ) 高度に抽象化されており Web に関する雑多な知識が不要 (HTTP HTML JavaScript など ) 本当に GUI アプリを作る感覚でよい
インストール SeasideJOne を使うのが最も簡単 http://swikis.ddo.jp/umejava/seasidejone zip を展開して 起動するのみ ダウンロードから 10 秒で立ち上がる Web アプリケーションサーバ + 開発環境 Seaside 2.8 + 日本語化パッチ (SeasideJ) Windows, Mac, Linux 共通 USB メモリに入れて持ち運べば どこでも開発できる!
最初のアクセス 管理ツールにアクセス http://localhost:9090/seaside/config ユーザ名 : admin パスワード : seaside Seaside サーバが提供しているアプリケーション ( コンポーネント ) 群が表示される
デモの確認 Counter にアクセス http://localhost:9090/seaside/examples/counter ++ や--のリンクをクリックしてみる ブラウザのbackボタンを押してみる 複数のブラウザを立ち上げてアクセスしてみる
何がうれしいのか? 継続 (Continuation) の威力 アプリケーションの状態をきめ細かくサーバ側に保持 リクエストごとに接続が切れる HTTP なのに! ブラウザの Back ボタンを押しても大丈夫
URL の秘密 自動生成される URL をよく見ると... http://localhost:9090/seaside/examples/coun ter?_s=dprpbmsjowwmwoki&_k=vatuosrj _s=dprpbmsjowwmwoki セッション ID ユーザを特定 _k=vatuosrj 継続 ID ユーザのアクションを特定
ステートフルな Web ユーザのアクションごとに状態を保持 あるアクションを何度でも実行できる Web アプリでもっとも苦労する部分を気にしなくとも良い
充実の開発環境 Web ブラウザから ハロー インスペクタ ブラウザ スタイルシートエディタ プロファイラ さらに Smalltalk のデバッガと連携 インタラクティブな開発環境が 強力に開発を支援してくれる
コンポーネントとは MVC の V と C に該当する部品 HTML を生成して (V) ユーザからのイベントを受け付ける (C) WAComponent コンポーネントの抽象クラス Seaside でアプリを作るときは まずこのクラスを継承する
コンポーネントの定義 WAComponent のサブクラスとして MyComponent を定義 MyComponent を Seaside に登録する MyComponent class>>initialize self registerasapplication: 'sample' 定義して MyComponent initialize を do it http://localhost:9090/seaside/sample 白紙の画面が表示される
コンポーネントの表示 ( レンダリング ) HTML を直に書かない 他の Web アプリ開発フレームワークで見られるような いわゆるテンプレートは使わない テンプレートは生きたコードではない 正しい HTML になるかのチェックが大変 デバッグも面倒 Smalltalk の開発環境でチェックできない メッセージ送信でより簡単に HTML を生成できる
001 レンダリングの手順 WAComponent>>renderContentOn: html をオーバーライド 引数として WARenderCanvas のインスタンスがやってくる MyComponent>>renderContentOn: html html text: ' こんにちは '
002 レンダリングの例 リスト html orderedlist: [ #(foo bar) do: [:each html listitem: [ html text: each]]]. テーブル html table: [ html tablerow: [ #(foo bar) do: [:each html tabledata: [html text: each]]]]. イメージ html image form: ActiveWorld submorphs first imageform.
002-2 見栄えの指定は? レンダリング時に class: や id: などで css のスタイルを設定 MyComponent>>renderContentOn: html html heading class: 'topic'; with: ' 見出しです '. html paragraph class: 'contents'; with: ' これが Seaside'. html div class: 'cool'; with: [ html orderedlist: [ #(foo bar) do: [:each html listitem: [ html text: each]]]. ]
002-2 スタイルシートメソッド WAComponent>>style をオーバーライド css の文字列を返す ブラウザからCSSエディタで編集 確認が可能 MyComponent>>style ' h1 { test-align: center; }.topic { color: red;}.contents { color: blue; }.cool { margin: 5%; } li { background-color: #ecf3e1; border: 1px solid #c5dea1; } '
003 コンポーネントの処理 ( コールバック ) GUI でいうところの イベントハンドラ リンクやフォームのボタンが押されたときの処理を記述する Smalltalk のブロックで書く html anchor callback: [self inform: Time now]; with: ' 今の時刻は?'
004 コールバックの例 フォームの場合 morph morph := ActiveWorld submorphs first. html form: [ html textinput value: morph extent; callback: [:value morph extent: (Point readfrom: value)]. html submitbutton value: ' サイズ変更 '. ]. html image form: morph imageform
005 簡略版コールバック on:of: を使ってモデルと関連づける html form: [ html textinput on: #name of: customer. html textinput on: #address of: customer. html submitbutton. ] callback: の簡略版 customer の name address メソッドが呼ばれて値が表示される Submit すると customer の name: address: メソッドが呼ばれて値が入る
状態の保持 単にコンポーネントにインスタンス変数を定義すればよい 手動でセッションの辞書に値を出し入れなどしない 継続により状態を保持したい変数群については states メソッドで明示的に示す ( ブラウザの Back ボタン対応 ) MyComponent>>states Array with: object. object は self でもインスタンス変数でも良い
005-2 コンポーネントの遷移 call: とanswer: 別のコンポーネントに制御を移すにはcall: を使う 新たな ( モーダル ) ダイアログを開くイメージ いつでも answer: で call: した側に戻ることができる 画面遷移のための XML など不要! answer: B A>>methodA value := self call: (B new) B>>methodB self answer: value A call:
継続の制御 Back ボタンで戻ることができない処理の区切りを作りたい場合 WAComponent>>isolate: を使う 継続の区切り ブロック内でしか 行き来できない ワークフロー的な処理の流れを示すための WATask クラスが用意されている WATask>>go をオーバーライドする WAStoreTask を参照のこと
ワークフロー記述の例 MyShoppingTask>>go cart := WAStoreCart new. self isolate: [[self fillcart. self confirmcontentsofcart] whilefalse]. self isolate: [ shipping shipping := self getshippingaddress. self shipto: shipping]. self displayconfirmation.
Seaside の得意分野 複雑な処理の流れを持つ Web アプリであっても簡単に作れる 継続の威力 単純な CRUD であれば Rails でいいが... オブジェクト指向を駆使したくなるような複雑なドメインの Web アプリ構築に向いている
その他 便利な部品群 WASimpleNavigation タブを使ったページの切り替え WATableReport リッチなテーブルの表示 ( ソート機能など ) WALabelledFormDialog ラベル付きフォームの生成 WABatchedList 複数ページビュー ( ページング ) の作成
Seaside の拡張 ShoreComponents 便利なウィジェット群 http://www.squeaksource.com/shorecomponents.html BeachSand Configuration をファイルに保存 http://squeaksource.blueplane.jp/beachsand.html Magritte モデルのメタ情報からコンポーネントを自動生成する http://www.lukas-renggli.ch/smalltalk/magritte Scriptaculous Scristaculous (Web 2.0 系の JavaScript ライブラリ群 ) JavaScript を意識せずに Seaside から利用できる 2.6 から Seaside に搭載済み
008 Scriptaculous の例 onclick: で effect を指定 MyComponent>>renderContentOn: html html heading id: 'topic'; with: ' 見出しです '. html anchor onclick: (html effect id: 'topic'; toggleblind); with: ' これが Seaside'. Configure リンクの Libraries から SULibrary を MyComponent に追加
モデルや DB との接続 コンポーネントとモデルの分離 モデルは コンポーネントとはまったく独立して定義できる コンポーネントは 単にモデルをインスタンス変数で保持すればよい DB との接続 RDB を想定しない モデルをどのような永続化の仕組みで保存しようが自由 RDB, OODB, File など
運用について Squeak を headless モード ( 画面無し ) で起動 squeak headless <your.image> Apache との組み合わせ ProxyPass と ProxyPassReverse を httpd.conf で設定 SSL の使用 ProxyPass /seaside/ http://localhost:9090/seaside/ ProxyPassReverse /seaside/ http://localhost:9090/seaside/ Seaside そのものは SSL をサポートしない Stunnel などを間に置くことで代用 http://www.stunnel.org/
システム開発事例 (1) Dabble DB (Seaside) Web 上の簡単データベース スプレッドシートの UI を用いて Web 上に自分用のデータベースアプリを簡単につくることができる http://www.dabbledb.com/
システム開発事例 (2) CMS BOX Seaside+Scriptaculous ベースの CMS 全てのページをインラインで編集 D&D や Undo のサポート http://www.cmsbox.ch/
システム開発事例 (3) Gjallar バグトラッキングシステム ワークフロー フォームなどを自由にカスタマイズ可能 http://www.gjallar.se/
GLASS GemStone, Linux, Apache, Seaside, and Smalltalk の略 http://seaside.gemstone.com/ Seaside のバックエンドを GemStone にしてしまう OR マッピングが不要 Continuation が永続化できる まだベータ版 登録すればダウンロードが可能
seabreeze Georg Heeg ek 製の Seaside 拡張 http://seabreeze.heeg.de/ Web ブラウザから WYSIWYG で Seaside の画面を作成できる
まとめ Seasideは Webアプリケーションを迅速に作るためのフレームワーク Webのしがらみを離れて すべてをオブジェクト指向で 自然に 書いていくことができる Ver. 2.9の開発が急速に進行中 Watchしていればきっと時代の最先端 http://seaside.st 連載 : SeasideへGO!! オージス総研 オブジェクトの広場 で 7 月から http://www.ogis-ri.co.jp/otc/hiroba/index.html