Project Zeroとは?
ここ数年で、Webアプリケーション開発の分野は大きく様変わりしました。Web2.0というキーワードで代表されるような、高機能で使い勝手のよいWebアプリケーションが当たり前のように求められるようになり、AjaxやREST、マッシュアップをいかに使いこなすかということが重要になってきています。また、従来に比べ開発期間が短縮される傾向にあることも、最近のWebアプリケーション開発の特徴ではないでしょうか。
Project Zeroは、このような新しい流れに対応すべく開発された、IBM発の次世代Webアプリケーションプラットフォームです。Project Zeroの特徴としては以下が挙げられます。
- シンプルで軽量:
Project ZeroはJava SEのみで動作するため、一般的なJava EEコンテナよりもはるかに少ないフットプリントで動作します。また、プラットフォーム全体が徹底的にモジュール化されており、コアモジュールはわずか数MBしかありません。
- アジャイルな開発スタイル:
Project Zeroのランタイム上で動作するアプリケーションはPHPおよびGroovyというスクリプト言語で開発することができます。コンパイルやパッケージングが必要ないため、アプリケーションの開発サイクルを早く回すことが可能です。
- Web2.0との親和性:
Project Zeroにおけるサービスの標準はRESTであり、サービスの実装方法は非常にシンプルです。データの扱いにおいても、JSONやXML、Feed(RSS,Atom)といったWeb 2.0アプリケーションでよく利用される形式に標準で対応しています。また、Dojo Toolkitに対応しており、Ajaxアプリケーションの開発が容易に行えます。
- マッシュアップ:
Project ZeroはAssemble Flow Editorというビジュアルなサーバーサイドマッシュアップツールを提供しており、Webブラウザー上で見通し良くマッシュアップ開発を行うことができます。
- ワンストップ:
Project Zeroはランタイムのみならず、開発ツールもセットで提供しています。開発ツールはEclipseプラグインの他に、Webブラウザーのみで開発が可能なApplication Builderを提供しており、どちらも無償で利用することができます。
- Java資産の有効活用:
Project Zero自体はJavaで構築されており、既存のJavaライブラリをProject Zero上でそのまま利用することができます。
Project Zeroは2006年にIBM社内のインキュベーションプロジェクトとして開発がスタートし、2007年6月にプロジェクトのWebサイトが公開されました。その後、Project Zeroの成果に基づいて2008年6月に製品版であるWebSphere sMash V1.0が日本でリリースされています。WebSphere sMash V1.0のリリース後もProject Zeroの最新版の開発は進められており、Webサイトで常に最新版が公開されるようになっています。Project ZeroはRed Hat Linuxに対するFedora Coreのようなものと考えていただければ分りやすいかもしれません。また、WebSphere sMashの開発者向けエディションであるDeveloper Edition(DE)については、製品版のバイナリと全く同じものをWebサイトからダウンロードして無償で利用することができます。
Project Zeroのもう一つの特徴が、オープンな開発スタイルです。Project Zeroは商用ソフトウェアを開発するための新しい試みとして、CDCD(Community Driven Commercial Development)という方法を採用しています。この意図は、OSSと商用ソフトウェアの良いところを組み合わせることにあり、OSSの特徴であるコミュニティからのフィードバックと、商用ソフトウェアの特徴である品質面の担保の両立を目指しています。プロジェクトのWebサイトでは、バイナリだけでなくソースコードリポジトリやロードマップ、開発者フォーラム、BugZillaなど、ほぼ全ての情報が公開されています。さすがにソースコードのコミット権はIBMの開発者にしか与えられていませんが、商用ソフトウェアとしては考えられないほどオープンであることがお分かり頂けるのではないでしょうか。
Project Zero(WebSphere sMash)のインストール
それでは、早速Project Zeroを使ってみましょう。ただし、Project Zeroのlatest buildは頻繁に更新されていますので、本記事ではより安定したバージョンである無償の開発版(WebSphere sMash DE)を利用することにします。
Project Zeroを利用するためには、JDK 5.0以上が必要です。事前にJDK 5.0以上をインストールし、環境変数JAVA_HOMEを適切に設定しておいてください。また、開発環境としてはWindows/Linux/Mac OSが利用できます。本記事ではWindows XP(SP2)およびJDK 6.0で動作確認を行っています。
まず、Project ZeroのWebサイトにアクセスし、右上のメニューから[Download]をクリックします。
ダウンロードページが表示されます。本記事執筆時点での最新バージョンは、2008年12月にリリースされたv1.1です。
「zero.zip」へのリンクをクリックします。
License Agreementの内容を確認し、問題がなければ[Accept]をクリックします。
[Download WebSphere sMash 1.1 CLI]のリンクをクリックし、zipファイルを保存します。
保存したzipファイルに含まれる「zero」ディレクトリ以下すべてを、適当なディレクトリに展開します。本記事ではこれ以降、展開先のディレクトリを<ZERO_HOME>と表記します(例えば、c:\smashDE11にファイルを展開した場合、<ZERO_HOME>はc:\smashDE11\zeroとなります)。
zero.bat(Linux/MacOSの場合はzero)が起動用コマンドになっていますので、<ZERO_HOME>にパスを通しておいてください。
以上でインストールは終了です。環境設定が正しく行われているか確認するために、コマンドプロンプト(シェル)を開き、「zero version」を実行してみてください。
sMashのバージョンやJDKのバージョンが表示されれば、環境設定は正しく行われています。もしうまく動作しない場合は、JAVA_HOMEやPATHなどの設定を確認してください。
実は、インストール直後の状態では「zero version」を実行するためのモジュール(zero.cli.tasks)すら含まれていませんが、必要なモジュールはリモート・リポジトリーから自動的にダウンロードされるので特に気にする必要はありません。また、ダウンロードしたモジュールはローカルにキャッシュされるので、2回目以降はリモート・リポジトリーへのアクセスは発生しません。
インターネットにプロキシーサーバー経由で接続されている場合は、zero.batを修正してプロキシー設定を追加してください。
Application Builderの起動
続いて、Webブラウザーベースの開発環境であるApplication Builder(以下、AppBuilder)を起動します。AppBuilderはそれ自身がsMashで開発されたWebアプリケーションであり、初回起動時にリモート・リポジトリーから自動的にダウンロードされてセットアップされます。AppBuilderの実行にはFirefoxが必要ですので、事前にインストールしておいてください。Firefoxは、mozillaのWebサイトからダウンロードできます。
Application Builderは、コマンドプロンプト(シェル)から「appbuilder open」を実行すれば起動できます(全てのモジュールのダウンロードには数分かかりますので、コーヒーでも飲んで一服しながら待ちましょう)。モジュールのダウンロードが完了すると、Firefoxが自動的に開き、AppBuilderの初期画面が表示されます。
AppBuilderはWebブラウザーを閉じただけでは終了しないので、終了する際にはコマンドプロンプト(シェル)から「appbuilder stop」を実行してください。
RESTサービスの開発
Project Zeroでは、Zero Resource Model(ZRM)という仕組みを提供しています。ZRMを利用すると、リソースの項目定義を行うだけで、DBに対するテーブルの作成やデータのCRUDを行うためのSQLの発行、RESTサービスのハンドラー実装を自動化することができ、定型的なコーディングを大幅に削減することが可能です。
ここでは、AppBuliderを利用してZRMによるRESTサービスを実装してみましょう。RDBMSは、Project Zeroがデフォルトで対応しているApache Derbyを利用します。
リソースの項目は次の通りです。
項目名 | タイプ | 備考 |
title | String(MaxLength:50) | |
author | String(MaxLength:50) | |
publisher | String(MaxLength:50) | |
category | String(MaxLength:50) | |
id | Integer | プライマリー・キー ※自動的に追加される |
updated | DateTime | ※自動的に追加される |
AppBuilderのスタート画面で[Create new application]をクリックします。
アプリケーションの基本情報を入力する画面が表示されるので、以下のように入力し、[Create]ボタンを押します。
- Application name : BookApp
- Root directory : (任意の空ディレクトリ)
以下のように表示されれば、アプリケーションの新規作成は完了です。
アプリケーション一覧から[BookApp]をクリックしてアプリケーションを開くと、File Editorに切り替わります。
リソースの項目定義は、モデル・ファイルと呼ばれるJSON形式のテキストファイルとして作成します。モデル・ファイルはテキストエディタで直接作成することもできますが、今回はAppBuilderのモデル・エディターを利用して作成します。
File Editorで、[New File]-[Zero Resource Model in /app/models]-[New Model]を選択します。
「File Create」ダイアログで、ファイル名を「/app/models/books.json」とし、[Create]を押します。
ZRM(Zero Resource Model)を扱うためのモジュールが依存モジュールとして定義されていないため、追加を促すダイアログが表示されるので、[Add]をクリックします。この操作により、依存モジュールの定義ファイル(config/ivy.xml)が自動的に修正されます。
モデル・エディターが開きます。この時点では、モデル・ファイルは空です。
[String]をクリックすると、文字列型の項目が追加されます。
プロパティ設定ボタン(×ボタンの左)をクリックすると、設定画面が開きます。ここでは「name」を「title」に変更し、それ以外はデフォルト設定のままとします。
同様にして、文字列型の項目を3つ追加し、「name」を「author」「publisher」「category」とします。
[Source]タブをクリックすると、モデル・ファイルのソース(JSON形式)が確認できます。
次に、DB作成時に初期投入するデータ(fixtures)を作成します。File Editorで、[New File]-[Other File]を選択します。
ファイル名を「/app/models/fixtures/initial_data.json」とし、[Create]を押します。
空のファイルが作成されエディタが開くので、以下のとおり入力します。
[ { "type": "books", "fields": { "id" : "1", "title" : "The End of History", "author" : "Fukuyama Francis", "publisher" : "Free Press", "category" : "Sociology"} }, { "type": "books", "fields": { "id" : "2", "title" : "The Clash of Civilizations", "author" : "Huntington Samuel", "publisher" : "Free Press", "category" : "Political Science"} }, { "type": "books", "fields": { "id" : "3", "title" : "Cloud Computing", "author" : "Miller Michael", "publisher" : "Que", "category" : "Computer Science"} } ]
次に、作成したモデル定義と初期データを利用して、DBにテーブルを作成します。[Console]タブを開き、[Command Prompt]を選択します。この画面から、sMashに対するコマンドを実行することができます。
「zero model sync」と入力し、リターンを押します。
command> zero model sync
以下のように、CREATE TABLE文が自動生成され、実行されます。また、初期データも登録されていることが分かります。
コマンド> zero model sync CWPZC9225I: デフォルトの Derby データベース構成を使用しています。 アプリケーション・ルートの db/resource にあります。 CWPZC9223I: 1 モデル・タイプが見つかりました CWPZC9212I: SQL -> CREATE TABLE books ( title VARCHAR(50), author VARCHAR(50), publisher VARCHAR(50), category VARCHAR(50), id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 100, INCREMENT BY 1) NOT NULL, updated TIMESTAMP NOT NULL ) を使用してタイプ -> books で作成されたテーブル -> BOOKS File -> C:\workshops\handson\handson06.RESTDB.03.ZRM\app\models\fixtures\initial_data.json CWPZC9214I: メンバーが作成されました タイプ -> books データ -> {title=The End of History, author=Fukuyama Francis, id=1, publisher=Free Press, category=Sociology} CWPZC9214I: メンバーが作成されました タイプ -> books データ -> {title=The Clash of Civilizations, author=Huntington Samuel, id=2, publisher=Free Press, category=Political Science} CWPZC9214I: メンバーが作成されました タイプ -> books データ -> {title=Cloud Computing, author=Miller Michael, id=3, publisher=Que, category=Computer Science} CWPZT0600I: Command model sync was successful
次に、RESTサービスのハンドラーを実装します。File Editorで、[New File]-[Resource Handler in /app/resources]を選択します。
ファイル名を「/app/resources/books.groovy」とし、[Create]を押します。
RESTサービスの実装となる、リソース・ハンドラーの雛型が自動生成されます。
通常はここで生成されたメソッドの内部を実装することでリソースに対するCRUD操作を定義することになりますが、今回はサービスの実装をZRMに委譲するため、個別のメソッド実装は不要です。
自動生成されたメソッドをすべて削除し、「ZRM.delegate()」の一行のみを記述します。
以上で、RESTサービスの実装は終了です。
次に、アプリケーションを起動して、RESTサービスをテストしてみましょう。画面右上の[Start]ボタン(緑色)をクリックします。
起動が完了すると、ボタンが[Stop](赤色)に変化します。
RESTサービスのテストには、FirefoxのPosterプラグインを利用すると便利です。ここではPosterプラグインを利用することを前提にテスト手順を説明します。
Firefoxの右下隅にある黄色の[P]ボタンを押すとPosterプラグインが別ウィンドウで開きます。
まず、GETのテストを実行してみましょう。
Posterの各プロパティを次のように構成し、ActionsセクションのHTTPメソッド(デフォルトではGETが選択されている)横の[GO]ボタンを押します。
- URL:http://localhost:8080/resources/books
- Actions(HTTPメソッド):GET (デフォルト値)
Responseウィンドウが表示されて、テキスト・エリアに次の3つの書籍情報がJSON形式で表示されたら、テストは成功です。
[{"title":"The End of History","author":"Fukuyama Francis","publisher":"Free Press","category":"Sociology","id":1,"updated":"2008-09-18 21:39:21"}, {"title":"The Clash of Civilizations","author":"Huntington Samuel","publisher":"Free Press","category":"Political Science","id":2,"updated":"2008-09-18 21:39:21"}, {"title":"Cloud Computing","author":"Miller Michael","publisher":"Que","category":"Computer Science","id":3,"updated":"2008-09-18 21:39:21"}]
[Close]ボタンを押して、Responseウィンドウをクローズします。
次に、POSTのテストを実行します。
Posterの各プロパティを次のように構成し、ActionsセクションのHTTPメソッド(デフォルトではGETが選択されている)横の[GO]ボタンを押します。
- URL:http://localhost:8080/resources/books
- Content Type:application/json
- Actions(HTTPメソッド):POST
- Content to Send: {"title":"The Secret","category":"Personal Transformation","publisher":"Atria Books","author":"Rhonda Byrne"}
Responseウィンドウが表示され、上部にあるStatusが201となっていたら成功です。Responseウィンドウをクローズします。
POSTで書籍情報が確かに追加されたか、GETリクエストを送信して確認してみます。Posterの各プロパティを次のように構成し、ActionsセクションのHTTPメソッド(デフォルトではGETが選択されている)横の[GO]ボタンを押します。
- URL:http://localhost:8080/resources/books
- Actions(HTTPメソッド):GET
Responseウィンドウのテキスト・エリアに、下記のように4冊分の書籍情報がJSON形式で表示されたら、テストは成功です。たった今POSTリクエストで追加した書籍情報のidをメモしておきます(idは自動採番なので実行時に決まります。これ以降、POSTで追加された書籍情報のidを100として手順を説明しますが、みなさんは実行時に採番されたidで適宜読み替えて進めてください)。
[{"title":"The End of History","author":"Fukuyama Francis","publisher":"Free Press","category":"Sociology","id":1,"updated":"2008-09-18 23:09:22"},{"title":"The Clash of Civilizations","author":"Huntington Samuel","publisher":"Free Press","category":"Political Science","id":2,"updated":"2008-09-18 23:09:22"},{"title":"Cloud Computing","author":"Miller Michael","publisher":"Que","category":"Computer Science","id":3,"updated":"2008-09-18 23:09:23"},{"title":"The Secret","author":"Rhonda Byrne","publisher":"Atria Books","category":"Personal Transformation","id":100,"updated":"2008-09-18 23:22:55"}]
[Close]ボタンを押して、Responseウィンドウをクローズします。
次に、PUTのテストを実行します。
先ほど追加した書籍情報のcategoryを「Mental Healing」に変更します。Posterの各プロパティを次のように構成し、ActionsセクションのHTTPメソッドの横の[GO]ボタンを押します。
- URL:http://localhost:8080/resources/books/100
(上記URL中の「100」はPOSTで追加したレコードに動的に割り当てられたidの値です。前の手順でメモした値を設定してください) - Content Type:application/json
- Actions(HTTPメソッド):PUT
- Content to Send: {"title":"The Secret","category":"Mental Healing","publisher":"Atria Books","author":"Rhonda Byrne"}
Responseウィンドウが表示されます。上部にあるStatusが200となっていたら成功です。Responseウィンドウをクローズします。
PUTで書籍情報が確かに更新されたか、GETリクエストを送信して確認してみます。Posterの各プロパティを次のように構成し、ActionsセクションのHTTPメソッド横の[GO]ボタンを押します。
- URL:http://localhost:8080/resources/books/100
(上記URL中の「100」はPOSTで追加したレコードに動的に割り当てられたidの値です。前の手順でメモした値を設定してください) - Actions(HTTPメソッド):GET
Responseウィンドウが表示されて、テキスト・エリアに次の1つの書籍情報がJSON形式で表示されると同時に、categoryがMental Healingになっていたら、テストは成功です。
{"title":"The Secret","author":"Rhonda Byrne","publisher":"Atria Books","category":"Mental Healing","id":100,"updated":"2008-09-18 23:32:09"}
[Close]ボタンを押して、Responseウィンドウをクローズします。
最後に、DELETEのテストを実行します。
Posterの各プロパティを次のように構成し、ActionsセクションのHTTPメソッド横の[GO]ボタンを押します。
- URL:http://localhost:8080/resources/books/100
(上記URL中の「100」はPOSTで追加したレコードに動的に割り当てられたidの値です。前の手順でメモした値を設定してください) - Actions(HTTPメソッド):DELETE
Responseウィンドウが表示されて、上部のStatusが200になっていれば、テストは成功です。[Close]ボタンを押して、Responseウィンドウをクローズします。
これでテストはすべて完了ですので、Posterのウィンドウをクローズしてください。また、アプリケーションも停止しておきましょう。AppBuilderからアプリケーションのをクリックしてください。アプリケーションが停止するとアイコンが に変わります。
Flow Editorによるサーバーサイドマッシュアップ
サーバーサイドマッシュアップとは、複数のWeb APIやFeedを組み合わせて新しいサービスを素早く構築する手法のことです。例えば、複数のFeedを組み合わせて加工することで新しいFeedを生成するなど、いろいろな応用例が考えられます。
通常、このようなサーバーサイドマッシュアップを行うためには、何らかのプログラム言語を利用して加工を行うのが一般的です。しかし、Project ZeroではAssemble Flow Editorというビジュアルな開発ツールを利用して効率よくサーバーサイドマッシュアップを実行することができます。
ここでは、Assemble Flow Editorを利用してFeedを加工するマッシュアップ・アプリケーションを実装してみましょう。
AppBuilderのスタート画面で[Create new application]をクリックします。
アプリケーションの基本情報を入力する画面が表示されるので、以下のように入力し、[Create]ボタンを押します。
- Application name : FeedApp
- Root directory : (任意の空ディレクトリ)
以下のように表示されれば、アプリケーションの新規作成は完了です。
アプリケーション一覧から[FeedApp]をクリックしてアプリケーションを開くと、File Editorに切り替わります。
Flowを新規作成しましょう。File Editorで[New File]-[Flow in /public]を選択します。
ファイル名に「/public/feed/index.flow」と入力し、[Create]をクリックします。
Flowの動作に必要なモジュールの追加を促す「Missing Dependency」が表示されるので、[Add]をクリックしてモジュールを追加してください。
空のFlowが作成され、自動的にFlow Editorが開きます。
手始めに、外部から取得したFeedをそのまま表示するフローを作成してみましょう。
画面右側のツールパレットで「Built-in Activities」グループを選択し、receiveGETアクティビティを中央の編集ペインにドラッグ&ドロップします。
receive-replyGETと間違えないように注意して下さい。
ドロップしたアクティビティをクリックし、名前を「rcv」に変更します。
同様に、replyGETアクティビティを配置し、名前を「rpy」に変更します。
次に、Feedを取得する処理を追加します。画面右側のツールパレットで「Feed Activities」グループを選択し、feedアクティビティをドラッグ&ドロップします。
配置したアクティビティをダブルクリックし、プロパティを以下の通り設定して、OKをクリックします。
- name: Codezine
- url: http://rss.rssad.jp/rss/codezine/new/20/index.xml
「rcv」と「Codezine」をリンクで接続します。「rcv」をクリックし、右側の丸印をドラッグ&ドロップして、「Codezine」に接続してください。
同様にして、「Codezine」と「rpy」を接続します。ここまでの結果は次のようになります。
メニューから「checkpoint」を選択し、作業内容をマークしておきます。
AppBuilderはファイルを自動保存しますので、特定時点の作業内容に戻りたい場合や、不具合によって作業内容が失われた場合の回復に備えて、定期的にチェックポイントをマークするようにしてください。
画面右上の開始ボタンをクリックして、アプリケーションを起動します。
新しくFirefoxのウィンドウを開き、アドレスバーに次のURLを入力します(Ctrl-Nで新しいウィンドウ、Ctrl-Tで新しいタブが開きます)。
http://localhost:8080/feed/index.flow
フローの実行が完了すると、以下のように表示されます(Firefoxの機能によって表示が整形されていますが、実際のレスポンスはAtomフォーマットのXMLです。興味のある方はソース表示でご確認ください)。
receiveGETやreceivePOSTなど、HTTPリクエストに対応するアクティビティを含むフローは、それ自身が新たなRESTサービスとして動作します。Flowに対してリクエストを送信することができるのはそのためです。
次に、先ほど作成したFlowを修正して、複数のFeedを集約するようにします。
アプリケーション・ビルダーに戻りましょう。
feedアクティビティを追加配置し、プロパティを以下の通り設定して[OK]をクリックします。
- name: dW
- url: http://www.ibm.com/developerworks/jp/rss/dw_dwjp.xml
「rcv」と「dW」を接続します。
2つのfeedを集約するために、aggregateFeedアクティビティを配置し、プロパティを以下の通り設定して[OK]をクリックします。
- name: aggregate
以下を接続します。
- 「Codezine」 → 「aggregate」
- 「dW」 → 「aggregate」
「CodeZine」と「rpy」のリンクを切断します。リンクのラインをクリックし、ツールパレットから[×]をクリックしてください(ラインの近くにアクティビティがあって操作しづらい場合は、アクティビティを移動してください)。
ここまでの結果は次のようになります。
aggregateで集約した結果をソートするために、sortFeedアクティビティを配置し、プロパティを以下の通り設定して[OK]をクリックします。
- name: sort
- sortBy: atom:title
- order: Ascending
以下を接続します。
- 「aggregate」 → 「sort」 → 「rpy」
ここまでの結果は次のようになります。
新しくFirefoxを開き、アドレスバーに次のURLを入力してフローの動作を確認します。
http://localhost:8080/report/index.flow
次のように、2つのFeedがマージされ、タイトルのアルファベット順にソートされて表示されます。
以上でFlowの開発は終了です。Feedを操作するアクティビティは他にもいろいろ用意されていますので、興味のある方は試してみて下さい。
作業が終了したら、アプリケーションを停止しておきましょう。AppBuilderからアプリケーションのをクリックしてください。アプリケーションが停止するとアイコンがに変わります。
AppBuilderを終了する場合は、コマンドプロンプト(シェル)から「appbuilder stop」を実行してください。
まとめ
本記事では、Project Zeroの概要と、AppBuilderによるRESTサービスの開発およびFlowの開発について簡単にご紹介してきました。Project Zeroが「シンプル」「軽量」かつ「アジャイル」な開発に適したプラットフォームであることが体感いただけたのではないかと思います。
Project Zeroに関する情報はhttp://www.projectzero.org/に集約されていますので、さらに詳しく知りたい方はぜひWebサイトをご参照いただければと思います。とはいえ、英語でのコミュニケーションはちょっと敷居が高いと感じる方もいらっしゃると思いますので、日本語でのコミュニケーションチャネルとして以下をご用意しています。
Project Zeroの開発者は、みなさんのフィードバックを待っています。ぜひ試していただき、ご意見をいただければ幸いです。