目次


Lift 2.0 の新機能

Comments

Lift の紹介

Lift は、Scala プログラミング言語を使って、強力でインタラクティブな動的アプリケーションを構築するために無料で使えるオープンソースの Web アプリケーション開発フレームワークです。Scala は純粋にオブジェクト指向ですが、関数型プログラミングもサポートしているという点が特徴的で、匿名関数やネストされた関数、そしてカリー化関数や高階関数などの機能も利用することができます。また、Scala は Java 仮想マシン (JVM) 上で実行されるため、Java のアプリケーションやライブラリーと共存することが可能です。これらの特徴は、Lift を使用している Web アプリケーションは Scala と Java クラス両方のライブラリーを使用できることを意味します。その上、Lift アプリケーションは WAR (Web Application Archive) ファイルとしてパッケージ化され、Servlet 2.4 仕様をサポートするあらゆる Web アプリケーション・サーバー (例えば、Apache Tomcat のバージョン 5.5 以降) にデプロイすることができます。

Lift の特徴の概略

Web アプリケーション・フレームワークとしての Lift は、セキュリティーとスケーラビリティーを高いレベルで維持し、信頼性の高いパフォーマンスと優れたユーザビリティーをユーザーに提供するアプリケーションを開発できるように後押しします。Lift アプリケーションはデフォルトで、クロスサイト・スクリプティング (XSS) 攻撃やクロスサイト・リクエスト・フォージェリー、そして悪意のあるデータ・インジェクションをはじめ、一般的な Web アプリケーションの脆弱性に対する耐性があります。

以下に挙げるのは、Lift によって Web アプリケーション開発者に提供される特徴の一部です。

  • リアルタイムのインタラクティブなプッシュ型 Web アプリケーションを開発するための世界最高レベルの Comet サポートを提供します。
  • Ajax (Asynchronous JavaScript and XML) リクエストを自動的に処理します。
  • サイト・マップ構成には、自動的にメニュー、簡潔な URL、セキュリティーおよびアクセス制御などが統合されます。
  • デザイナー・フレンドリーに作られた適切なビュー・テンプレート。これらの静的テンプレートには、アプリケーション・ロジックやプログラミング・コードが組み込まれることが一切ありません。
  • Lift アプリケーションは、Tomcat、Jetty、Glassfish、JBoss をはじめ、多種多様なアプリケーション・サーバーにデプロイすることができます。基本的に、Servlet 2.4 仕様をサポートする Java Web コンテナーであれば、何にでもデプロイすることが可能です。
  • ORM および ActiveRecord 永続層があらかじめ組み込まれています。
  • プロパティー・バンドル、ローカライズされたテンプレート、カスタマー・リソース・バンドル・プロバイダーにより、優れた国際化サポートを提供します。
  • 構文解析、クエリー、妥当性検証、変換、シリアライズをはじめとした機能で、JSON を強力にサポートします。
  • 宣言型ロジックによる卓越したフォーム検証により、HTTP リクエストを直接処理する必要がありません (LiftScreen および Wizard)。
  • Lift では RESTful な Web サービス API を提供するのは至って簡単です。
  • 増大し続けるウィジェットのライブラリーから、自動補完フィールド、日/週/月ビューのカレンダー、データ・グリッド、チャート、階層ツリー・コントロールなどのコンポーネントを組み込むことができます。
  • Lift の機能セットをさらに拡充する、OAuth や OpenID などのモジュールが追加されています。

世界で利用されている Lift

Lift は比較的新しい Web フレームワークではありますが (バージョン 1.0 がリリースされたのは 2009年 2月のことです)、すでに、いくつかの素晴らしい大規模プロジェクトで使用されています。なかでも特に注目に値するのは、ロケーション指向のソーシャル・ネットワーク、Foursquare で使用されていることです。このプロジェクトでは 2009年後半になって、プロジェクトの構成を PHP と MySQL から Lift と PostgreSQL へと変更しました。この移行が行われた後に Rasmus Lerdorf がつぶやいた「@foursquare には 4 つ星の評価を与えます。これは、私が調べたなかで久しぶりに目にした、セキュリティーの問題を (私の知る限り) 1 つも抱えていないサイトです」というツイートは広く知られるようになりました。

Lift に移行してからというもの、Foursquare は飛躍的に成長し、500 万ものユーザーが世界のいたるところからこのサイトを訪れていると報告されています。記事の「参考文献」セクションに、Foursquare の Harry Heymann 氏が Lift と Scala を使った自らの開発体験を発表しているプレゼンテーションへのリンクを記載してあるので参照してください。

Lift が使われているプロジェクトには、広く使用されている Novel の Vibe Cloud もあります。この製品には、エンタープライズ・ソーシャル・ネットワーキング機能、リアルタイムの連携および文書編集機能、ファイル共有機能、同期機能など、さまざまな機能が備わっています。Novell はこのフレームワークを使用する最大の利点の 1 つとして、Lift の優れた Comet サポートを挙げています (「参考文献」を参照)。

Lift を使用している名の知れたプロジェクトには、他にも Innovation Games、XMPie、Exchango、Snapshort、No Fouls などがあります。

Lift 2.0 の新機能を探る

Lift はバージョン 2.0 とそれ以降のリリースでは、バージョン 1.0 に対して大幅な改善が加えられ、新しい機能が追加されています。このセクションでは、このフレームワークの最新バージョンが提供する新機能を簡単に紹介します。

Lift 2.0

2010年 6月 30日に発表された Lift 2.0 は、バージョン 1.0 の大々的なアップグレードです。なかでも特に目覚ましい機能強化が行われた内容の一部を以下に記載します。

  • Comet サポートの改善
  • LiftScreen および Wizard を使用した宣言型のフォーム検証と入力
  • JSON の構文解析、妥当性検証、変換、およびクエリーのサポート
  • RESTful なサービスをデプロイするためのシンプルなインターフェース
  • デフォルトのまま使用できる NoSQL データベースのサポート (CouchDB および MongoDB)
  • Maven に加え、Simple Build Tool のサポート
  • JTA および LDAP のサポート
  • Servlet コンテナーの外部でアプリケーションを実行する機能

Lift 2.1

Lift 2.1 は、以下の改善内容を盛り込んで 2010年 9月 24日にリリースされましした。

  • Scala 2.8 のサポート
  • NoSQL データベース・サポートの改善
  • SQL データベース対応の Scala ORM および DSL である、Squeryl のサポート

Lift 2.2-RC2

2010年 12月15日、Lift チームは 2 番目のリリース候補バージョンとして、Lift 2.2 を発表しました。以下に挙げるのは、このリリースの特徴のごく一部でしかありません。

  • Scala 2.8.1 のサポート
  • HTML5 のサポート
  • Wiring 機能による従属ページ要素の自動更新
  • LiftScreen および Wizard 機能の改善
  • テンプレート内での CSS セレクター・トランスフォーム
  • 国際化対応の改善
  • セキュリティーの強化
  • MongoDB サポートの改善
  • Squeryl 統合の改善

デザイナー・フレンドリーなテンプレート

これまでに MVC Web アプリケーション・フレームワークを使ってプロジェクトを開発した経験があれば、テンプレート、あるいはビューの概念はもう十分に理解していることでしょう。ビューには、アプリケーションの外観およびプレゼンテーション層が、ビジネス・ロジックおよびプログラミング・コードとは切り離されて保持されます。このアーキテクチャーの目的の 1 つは、デザイナーにプログラミングの知識や作業をほとんど要求することなく、プロジェクトのデザイン要素をデザイナーが扱えるようにすることです。

実際のところ、この目的が達成されるケースは稀であり、多くの MVC アプリケーションのビューまたはテンプレートには、最終的にかなりの量のコードが含まれることになります。それは大抵の場合、条件付きロジックや繰り返し処理を実装するために、テンプレートやビューに何らかのプログラミング・コードが組み込まれるからです。例えば CodeIgniter フレームワークでは、複数の行を配列で表示する必要がある場合、ビューまたはテンプレートで PHP の短縮構文を使ってこの必要に対処するよう推奨されています。この推奨の明らかな問題は、テンプレートを扱う当人が、該当するプログラミング言語の構成体の構文を理解していなければならないことです。さらにもう 1 つの問題として、ビューにプログラミング・コードを組み込むと、標準の HTML エディターでテンプレートを編集するのも、W3C 妥当性検証ツールを使って文書の妥当性を検証するのも難しくなります。

リスト 1 に記載するテンプレートには、この問題の一例が示されています。ここに示したのは典型的なテンプレートで、オブジェクトの配列を繰り返し処理しなければなりません。そのためにこの例で使用しているのは、前述の CodeIgniter フレームワークと PHP の短縮構文です。

リスト 1. テンプレートにロジックを含めることによる問題を示す例
<h1>Vegetables</h1>
<ul>
    <?php foreach($vegetables as $vegetable): ?>
    <li><?php echo $vegetable; ?></li>
    <?php endforeach; ?>
</ul>

リスト 1 のコードで明らかな問題は、このコードは、デザイナーが PHP コードの基本的な構成体を扱い慣れていることを前提としている点です。デザイナーが PHP コードの一部を変更するのは簡単なため、それが原因でテンプレート全体が壊れてしまったとすると、テンプレート内部のロジックに潜む問題をデバッグするのは悪夢のような作業となります。

Lift は、静的なテンプレートにプログラミング・ロジックやシンボルを一切含めないことを第一の設計目標として作成されました。これにより、Dreamweaver などのデザイン・ツールでテンプレートを編集することが可能になり、デザイナーは検証ツールを使って HTML コードの検証を行い、検証に合格できるようになりました。

リスト 2 に、リスト 1 で作成したテンプレートを Lift で作成したコードを記載します。

リスト 2. Lift を使用することでプログラミング・ロジックを排除する例 (古い Lift のバージョンによる方法)
<lift:surround with="default" at="content">
    <h1>Vegetables</h1>
    <ul>
        <lift:vegetables>
            <li><vegetable:name /></li>
        </lift:vegetables>
    </ul>
</lift:surround>

テンプレートが改善されていることに、皆さんも同意していただけるはずです。まず、上記には煩わしい PHP タグも、foreach 構成体もありません。ここで使われているタグ構造のほうが、デザイナーにとっては遥かに馴染みがあります。そうは言っても、この手法では lift 名前空間の中でカスタム・タグを使用しているため、妥当な (X)HTML マークアップとして認められないという問題が残ります。妥当なマークアップにするには、この名前空間を明示的に定義する必要があります。けれども、HTML デザイン・テンプレートを作成するためだけに、名前空間を明示的に定義するのは行き過ぎです。

Lift のバージョン 2.2 では、class 属性の値を使用してスニペットの呼び出し方法を定義することができます。そのため、lift 名前空間を明示的に宣言しなくても、すべての Lift テンプレートに妥当性があることが適切に検証されます。カスタム・タグを使用する代わりに、Lift 2.2 では通常の妥当な HTML 要素を使用するため、すべてが HTML として妥当であると認められます。リスト 3 は、この手法で作成した場合のテンプレートです。

リスト 3. Lift 2.2 による妥当な (X)HTML テンプレート
<div class="lift:surround?with=default;at=content">
    <h1>Vegetables</h1>
    <ul class="lift:vegetables">
        <li><span class="name"></span></li>
    </ul>
</div>

この後すぐにわかりますが、上記の新たな手法でテンプレートを定義した場合、そのテンプレートにバインドされる Scala スニペットを作成するのは、以前よりも簡単になります。

HTML5 のサポート

デフォルトでは、Lift は XHTML を出力し、HTTP レスポンスのコンテンツ・タイプは UTF-8 文字セットが指定された application/xhtml+xml となります。もちろん、さまざまな理由で、XHTML マークアップを使用したくない場合もあります。Web アプリケーション開発を新しく定義する標準として HTML5 が登場したことから、コンテンツをブラウザーに送信する方法を選択できることが、今まで以上に重要になっています。

Lift 2.2 がリリースされるまでは、出力および入力を構文解析するには XHTML が唯一の選択肢でした。バージョン 2.2 でもデフォルトの選択肢は XHTML ですが、少なくともバージョン 2.2 には完全な HTML5 サポートを有効にするという選択肢があります。Lift における HTML の構文解析方法および出力方法を定義する各種のプロパティーは、HTMLProperties オブジェクトに保持されます。これらのプロパティーには、docTypeencodingcontentTypehtmlOutputHeaderhtmlParserhtmlWriterhtml5FormsSupportmaxOpenRequests、および userAgent があります。プロパティーの値はいずれも、LiftSession.sessionHtmlProperties および LiftSession.requestHtmlProperties を使用して、セッションの途中でも、リクエストの途中でも変更することができます。あるいは、XHTML ではなく、HTML5 を使用するようにデフォルト設定を変更するという方法もあります。それには、Boot.scala に以下の LiftRule を追加します。

LiftRules.htmlProperties.default.set((r: Req) =>new Html5Properties(r.userAgent))

このようにして HTML5 サポートを有効にすると、ページの標準 DOCTYPE が HTML5 宣言になります。さらに、レスポンスの Content-Type は text/html となり、HTML 構文は標準の Scala XML パーサーの代わりに nu.validator.htmlparser を使って解析されることになります。

CSS セレクター・トランスフォーム

Lift を使用したことのある誰もが知っているように、Lift は HTTP リクエストを入力から出力への変換として扱い、スニペットの関数を使用して値をテンプレート内のフィールドにバインドします。Lift 2.2 以降では、CSS セレクターを使って、スニペットをテンプレートにバインドできるようになっています。この方法がもたらす利点を理解するには、実際の CSS セレクター・トランスフォームの例を見てください。まず、かつての方法で値をテンプレートにバインドする例から見ていきます。リスト 4 に、以前のバインディング方式で使用されるテンプレートを示します。

リスト 4. 旧式のバインディングで使用するテンプレート
<div class="lift:surround?with=default;at=content">
    <h2>A simple example</h2>
    <span class="lift:example.hello">
       <p>Hi there, <span class="person:name />!</p>
    </span>
</div>

リスト 5 に示すスニペットは、リスト 4 のテンプレートに値をバインドします。

リスト 5. 値をテンプレートにバインドするスニペット
class Example {
    def hello(xhtml:NodeSeq) = {
        bind("person", xhtml, "name" -> "Joe")
    }
}

リスト 5 では、hello 関数が person:name 要素にバインドして、その要素の内容を値 Joe に置き換えます。その結果、リスト 6 に示すような出力となります。

リスト 6. 上記のスニペットによる出力結果
<div>
<h2>A simple example</h2>
<span>
    <p>Hi there, Joe!</p>
</span>
</div>

このテンプレートに少し手を加え、出力される内容で置き換える必要がある値に ID 属性を指定します (リスト 7 を参照)。

リスト 7. ID 属性を追加した変更後のテンプレート
<div class="lift:surround?with=default;at=content">
    <h2>A simple example</h2>
    <span class="lift:example.hello">
       <p>Hi there, <span id="name" />!</p>
    </span>
</div>

ここで、CSS セレクター・トランスフォームを使用して、ID 属性が “name” である要素の中に私の名前をレンダリングします (リスト 8 を参照)。

リスト 8. CSS ID セレクター・トランスフォームを使用した変更後のスニペット
class Example {
    def render = "#name" #> "Joe"
}

リスト 8 の結果は、リスト 6 の結果とまったく同じです。この例では、CSS ID セレクターを使用していますが、その他にもさまざまなセレクターを使用することができます。表 1 に、そうした例をいくつか記載します。

表 1. CSS セレクター・トランスフォームの例
セレクターテンプレート出力
"#name" #> "Joe"<span id="name" />Joe
"#name *" #> "Joe"<span id="name" /><span id="name">Joe</span>
"#name [rel]" #> "friend"<span rel="" id="name">Joe</span><span rel="friend" id="name">Joe</span>
".highlight" #> (n: NodeSeq) => n ("style", "color: red")<span class="highlight">Joe</span><span class="highlight" style="color: red">Joe</span>
"href=# [href]" #> "about:blank"<a href="#">Link</a><a href="about:blank">Link</a>

ご覧のように、CSS セレクター・トランスフォームの左側が、使用するセレクターと使用する置換ルールを定義します。使用できる CSS セクレターは以下のいずれかです。

  • ID (例えば、”#name”) は、ID が “name” に設定された要素を選択します。
  • クラス (例えば、”.highlight”) は、クラス名が “highlight” の要素をすべて選択します。
  • 属性値 (例えば、”href=#”) は、属性 href の値が “#” に設定された要素をすべて選択します。

置換ルールは Lift に対し、条件と一致する要素の中で置換する部分を指示します。置換ルールには、以下の 3 つのどれを適用することもできます。

  • 置換ルールを 1 つも使用しなければ、一致する要素全体が置換されます。
  • * は、一致する要素の内部にあるコンテンツを置換します。
  • [href] は、一致する要素の href 属性の値を置換します。

トランスフォームの右側は、テンプレート要素を置換するときに、どの値を使用するかを定義します。値は、以下のいずれかの型にすることができます。

  • String 定数
  • NodeSeq 定数
  • NodeSeq=>NodeSeq 変換関数
  • Bindable
  • StringPromotable 定数
  • IterableConst

CSS セレクター・トランスフォームは、Lift の当初のテンプレート・バインディング構文の代わりとなる強力かつ簡略化された手段です。CSS セレクターを使用してきた開発者 (例えば、jQuery や Dojo などの JavaScript ライブラリーを使用してきた開発者) は、この手段を使ったほうが賢明でしょう。

LiftScreen と Wizard

Lift 2.0 で導入された LiftScreen および Wizard という概念は、妥当性検証と状態管理の観点から Web フォームの扱い方を根本的に改善しました。どんな Web 開発者でも、いつかは従来の Web フォームの処理を経験することになるでしょう。従来の Web フォームの処理では、Web クライアント・サイドのフォームを、おそらく何らかの JavaScript を使って検証してから処理した後、サーバー・サイドで検証を行います。処理中に問題が発生した場合には、アプリケーションがそれに応じてレスポンスを返し、初めからやり直します。これは、かなり手のかかるプロセスです。その原因は主に、HTTP リクエストを行って、そのリクエストに応答するために必要な作業の量にあります。

このようなフォーム処理プロセスを簡易化するために、LiftScreen と Wizard は以下の機能を備えています。

  • 直接 HTTP を使用しないフォームの検証
  • 宣言型によるフォームの検証
  • 自動状態管理
  • ブラウザーの履歴管理 (「戻る」ボタンが効かないことは一切ありません)
  • 強い型付けのフォーム要素

LiftScreen では単一フォームで入力の処理と検証を行う一方、Wizard では複数のフォームで段階的に検証を進めて行きます。フォーム内では、「Next (次へ)」ボタンと「Previous (戻る)」ボタンを使ってセクション間をナビゲートする場合もあります。Lift の Wizard は、実際には Screen のコレクションであり、その表示順を決定するためのロジックが用意されています。例えば、各画面でのユーザー入力に応じて異なる画面を表示させたいとしたら、Wizard を使用してください。

まずは、リスト 9 の極めて単純な LiftScreen の例を見てください。

リスト 9. LiftScreen の基本
object WhatsMyName extends LiftScreen {
    val name = field(S ? "Please enter your name", "", 
valMinLen(1, "Name is a mandatory field"))
    def finish() {
        S.notice("Hello, "+name.is+"!")
    }
}

リスト 9 の画面を Lift テンプレートに追加する方法は、以下のとおりです。

<div class="lift:WhatsMyName" />

Wizard の背後にある概念は LiftScreen とまったく同じですが、複数の画面を使用できるという点が異なります。リスト 10 は、ある画面で自分の名前を入力し、別の画面で勤務先を入力する例です。

リスト 10. Wizard の基本
object PersonWizard extends Wizard {
    val screen1 = new Screen {
        val name = new Field with StringField {
            def title = S ?? "Please enter your name"
        }
    }

    val screen2 = new Screen {
        override def screenTop = <div>Hello {page1.name}!</div>

        val company = new Field with StringField {
            def title = S ?? "Please enter company name"
        }
    }

    val screen3 = new Screen {
        override def screenTop = <div>Hello {page1.name} who works in 
{page2.company}!</div>
    }
}

LiftScreen と Wizard は、私が (Comet は別としても) 今後を最も楽しみにしている Lift の要素です。Lift のデモ・ページに、Wizard の好例が紹介されています。LiftScreen の作成方法については、Lift のウィキに詳しく説明されています。

JSON のサポート

最近のソフトウェア開発では、軽量のデータ交換フォーマットである JSON (JavaScript Object Notation) が極めて一般的に使われるようになってきています。これは、Web アプリケーションの開発では特に言えることです。言語に依存しない優れた実装サポートを備え、最近の Web ブラウザーがネイティブに読み込めることから、これまで XML が使用されていたようなところで、代わりに JSON が使用されることが増えています。

Lift 2.0 では、JSON データを扱うための新しいライブラリーとして、lift-json を導入しました。このライブラリーには、以下の機能が含まれています。

  • JSON 構文解析
  • LINQ スタイルの JSON クエリー
  • シリアライズ
  • 簡潔な JSON 出力
  • JSON と XML との間の変換
  • XPath スタイルの式を使った操作
  • 2 つの JSON 式のマージおよび差分出力のサポート

lift-json ライブラリーは Lift フレームワークに組み込まれていますが、実際にはスタンドアロンのプロジェクトなので、Lift を使用しない他の Scala プロジェクトにも組み込むことができます。lift-json プロジェクトは、Github で fork することが可能です。また、優れた Readme が用意されており、このライブラリーの非常に詳しい説明がなされています (「参考文献」を参照)。

ここからは、lift-json がどのようにして JSON データを簡単に扱っているのか、例をいくつか紹介します。最初に取り上げるのは、Scala の型から JSON ストリングを作成する例です。

val json = JsonAST.render(List(1, 2, 3, 4, 5))

上記のステートメントによって、json の値には以下のストリングが含まれることになります。

[1,2,3,4,5]

このように、Scala の List は JSON 配列にマッピングされましたが、JSON オブジェクトについてはどうでしょう?その場合でも、Scala の ~ 演算子のおかげで簡単にマッピングすることができます。

リスト 11. Scala の List から JSON 配列へのマッピング
val obj = ("name" -> "Joe Lennon") ~ ("company" -> "Core International") 
~ ("email": "joe@joelennon.ie")
val json = JsonAST.render(obj)

この場合、JSON には以下のストリングが含まれる結果となります。

{"name":"Joe Lennon","company":"Core International","email":"joe@joelennon.ie"}

ご覧のとおり、JSON に変換するのは至って簡単ですが、JSON からの変換も、同じく簡単に行えるのでしょうか?そこで、最初の例での変換を逆にして、”[1,2,3,4,5]” というストリングから List を作成するとします。それには、lift_jsonparse 関数を使用することができます。

val obj = parse("""[1, 2, 3, 4, 5]""")

上記のステートメントは、指定された JSON 配列内の項目の List が含まれる JArray オブジェクトを生成します。つまり、以下のように表すことができます。

JArray(List(JInt(1), JInt(2), JInt(3), JInt(4), JInt(5)))

lift-json の詳細は、Github で公開されている Readme ファイルを参照してください。このファイルへのリンクは、「参考文献」セクションに記載されています。

NoSQL データベースのサポート

PostgreSQL、MySQL、SQL Server、Apache Derby などの従来のリレーショナル・データベースを含め、Lift は多種多様なデータベース・システムとともに使用することができます。さらに、Lift 2.1には Scala 用の ORM (Object-Relational Mapping) フレームワークである Squeryl がネイティブ・サポートされており、Lift の Mapper および Record 機能と Squeryl を直接統合できるようになっています。

最近では、非リレーショナル・データベース管理システムや、データベースの操作に SQL (Structured Query Language) を使用しないデータベース管理システムなどの、新しいデータベース管理システムへの関心が着実に高まっています。最もよく使用されている NoSQL データベースのうち、MongoDB と CouchDB はドキュメント指向のデータベースです。ドキュメント指向データベースでは、データが JSON のようなオブジェクト構成体に格納されるため、ほとんどの場合、データは自己完結型になります。これらのデータベースを使用するメリット (そして落とし穴) についての詳細は、この 2 つの新しいオープンソース・プロジェクトのそれぞれについて詳しく紹介している「MongoDB Cookbook」および「CouchDB を探る」を参照してください (「参考文献」にリンクを記載)。次のセクションでは、Lift 2.0 で MongoDB および CouchDB データベースと直接通信する方法を簡単に説明します。

MongoDB の操作

Lift 2.0 の MongoDB サポートは、lift-MongoDBlift-MongoDB-record という 2 つのコンポーネントによって提供されています。lift-MongoDB は、メイン・コードと MongoDB ドライバーが含まれるライブラリーです。このライブラリーを使ってデータベースと下位レベルで直接通信し、手動でドキュメントの作成ならびにデータベースの作成と管理を行うことができます。もう一方の lift-MongoDB-record は、MongoDB データベース用の Record フレームワークの実装を提供します。ここからは、MongoDB ドライバーを操作する基本的なコマンドをいくつか紹介します。

デフォルトとして使用するデータベースを定義するには、以下のコマンドを使用することができます。
MongoDB.defineDb(DefaultMongoIdentifier, MongoAddress(MongoHost("localhost", 27017), "my_database"))

このデータベースに接続してドキュメントを作成し、作成したドキュメントをコレクションに保存します (リスト 12 を参照)。

リスト 12. MongoDB の操作
MongoDB.use(DefaultMongoIdentifier) ( db => {
val doc = new BasicDBObject
     doc.put("name", "Joe Lennon")
      doc.put("company", "Core Intrernational")
      doc.put("email", "joe@joelennon.ie")
      val coll = db.getCollection("people")
      coll.save(doc)
})

データベースにドキュメントとして保存するオブジェクト・クラスを作成するには、MongoDocument ライブラリーを使用することができます。それにはまず、クラスの定義が必要です (リスト 13 を参照)。

リスト 13. Person オブジェクトのレコード構造を定義する
case Class Person(_id: String, name: String, company: String, 
email: String) extends MongoDocument[Person] {
      def meta = Person
}

object Person extends MongoDocumentMeta[Person] {
      override def mongoIdentifier = DefaultMongoIdentifier
      override def collectionName = "people"
}

これで、この型のドキュメントを作成することができます (リスト 14 を参照)。

リスト 14. Person 型のドキュメントを作成する
val person1 = Person(
    ObjectId.get.toString,
    "Joe Lennon",
    "Core International",
    "joe@joelennon.ie"
)

ドキュメントは、save 関数を呼び出すだけで保存することができます。

person1.save

find 関数を使用すれば、データベースからドキュメントを取得することができます。上記のドキュメントを取得するとしたら、この関数を以下のように使用します。

val person1Copy = Person.find(person1._id)

ドキュメントを削除するには、以下のコマンドを使用します。

person1.delete

MongoDB ドキュメントのその他の操作方法、そして lift-MongoDB-record コンポーネントの詳細な操作方法については、Lift のドキュメントを参照してください (「参考文献」を参照)。

CouchDB の操作

Lift の CouchDB サポートは、CouchDB の RESTful なインターフェースとの対話に必要な HTTP リクエストおよびレスポンスを自動的に処理するドライバーによって提供されます。早速、CouchDB データベースに接続する方法を見てみましょう (リスト 15 を参照)。

リスト 15. CouchDB データベースに接続する
val db = new Database("my_database")
db createIfNotCreated(new Http())
CouchDB.defaultDatabase = db

リスト 15 は、CouchDB データベース・オブジェクトを作成し、物理データベースが存在しない場合には物理データベースそのものを作成します。その上で、CouchDB に対し、このデータベースを使用するように指示します。次は、MongoDB のセクションで行ったように、Person オブジェクトのレコード構造を定義します (リスト 16 を参照)。

リスト 16. Person オブジェクトのレコード構造を定義する
class Person extends CouchRecord[Person] {
    def meta = Person

    object name extends StringField(this, 100)
    object company extends StringField(this, 200)
    object email extends StringField(this, 255)
}

object Person extends Person with CouchMetaRecord[Person] {
    def createRecord = new Person
}

レコード構造を定義したら、今度は Person オブジェクトを作成し、オブジェクトの 3 つのプロパティー (namecompany、および email) に値を指定して、このオブジェクトをデータベースに保存することができます (リスト 17 を参照)。

リスト 17. Person オブジェクトのレコード構造を使用してデータを CouchDB に保存する
val person1 = Person.createRecord.name("Joe Lennon")
.company("Core International").email("joe@joelennon.ie")
person1 save

属性の値はオンザフライで簡単に変更することができます。例えば、person1 の名前を “Joseph Lennon” に設定するとしたら、リスト 18 のコードを使用します。

リスト 18. 属性の値をオンザフライで設定する
person1.name.set("Joseph Lennon")
person1 save

CouchDB でデータに対してクエリーを実行する方法はかなり独特です。基本的には、データベース自体のデザイン・ドキュメントに永続的に保管された Map/Reduce の view 関数一式を使用します (その場で臨機応変にクエリーを実行することも可能ですが、その場合にはかなり速度が遅くなります)。Map/Reduce および CouchDB ビューについては、私の著書『Beginning CouchDB』でその全体を詳しく説明しています (「参考文献」にリンクを記載)。ここで、Lift を使用してドキュメントに対してクエリーを実行するためのデザイン・ドキュメントを作成してみましょう (リスト 19 を参照)。

リスト 19. CouchDB ビューのデザイン・ドキュメントを作成する
val design_doc: JObject =
    ("language" -> "javascript") ~
    ("views" -> (("all_people"-> ("map" -> "function(doc) 
{ if(doc.type === 'Person') { emit(doc._id, doc); } }"))))
Http(database.design("my_design_doc") put design_doc)

基本的に、リスト 19 のコードは、type 属性の値が Person となっているすべてのドキュメントに _id 属性による索引を付けて返す CouchDB ビューを作成します。このビューは my_design_doc という名前のデザイン・ドキュメントに保管されます。保管された後のビューは、以下の方法で使用することができます。

val results = Person.queryView("my_design_doc", "all_people")

CouchDB ドライバーを使用する Lift アプリケーションをセットアップする方法、そしてその使用方法に関する詳細な説明については、Lift のウィキを参照してください。

まとめ

この記事では、Lift Web アプリケーション開発フレームワークのバージョン 2.0 に導入された新機能および機能拡張について概説しました。まず、Lift の概要とその一般的な特徴を説明した後、Lift のバージョン 2.0、2.1、および 2.2-RC1 のそれぞれで新しく追加された機能を紹介しました。最後に、これらの新機能のうち、テンプレート・システムの改善と、HTML5、JSON、および NoSQL データベースのサポートの追加、そしてその他の機能 (LiftScreen、Wizard、Wiring など) について詳しく分析しました。この記事を読むことで、皆さんがこの素晴らしいオープンソースの Web フレームワークについてさらに詳しく探りたくなったようであれば幸いです。


ダウンロード可能なリソース


関連トピック

  • Lift の公式サイトにアクセスしてください。
  • Build Comet applications using Scala, Lift, and jQuery」(developerWorks、2009年3月) では、Scala、Lift、および jQueryの技術を使用してリアルタイムの Web オークションを構築する方法を説明しています。
  • Apache Geronimo に Lift を活用する」(developerWorks、2008年7月) では、Lift を使って Web アプリケーションを作成する手順、そしてそのアプリケーションを Geronimo にデプロイする手順を披露しています。
  • Scala についての詳細は、「多忙な Java 開発者のための Scala ガイド: オブジェクト指向のための関数型プログラミング」(developerWorks、2008年1月) を読んでください。
  • Scala と XML」(developerWorks、2008年4月) では、Scala を使用して、構文解析された XLM をナビゲートしたり、処理したりする方法を説明しています。
  • Lift サイトから提供されている「Exploring Lift」(Derek Chen-Becker、Marius Danciu、Tyler Weir 共著) を読んでください。
  • Lift のウィキにアクセスしてください。
  • チャット・アプリケーションのデモで、Lift を使用して Comet 対応のチャット・アプリケーションを作成する方法を学んでください。
  • Lift 2.2-RC2 の新機能について学んでください。
  • 『Beginning Scala』の著者である David Pollak が、Scala Lift について解説しています。
  • foursquare.com での Scala と Lift の利用方法に関するスライド・プレゼンテーションを見てください。
  • Novell のクラウド・サービスも Scala と Lift を使用して作成されました。
  • 公式 MongoDB サイトにアクセスしてください。
  • MongoDB の Map/Reduce 関数についての詳細を学んでください。
  • MongoDB Cookbook では、MongoDB の一般的なすべての使用方法について解説しています。
  • lift-json ライブラリーは Lift フレームワークに組み込まれていますが、実際にはスタンドアロンのプロジェクトなので、Lift を使用しない他の Scala プロジェクトにも組み込むことができます。lift-json プロジェクトは、Github で fork することが可能です。また、このライブラリーの詳細な説明を記載する readme も用意されています。
  • CouchDB を探る」(developerWorks、2009年3月) では、Apache によるオープンソースの CouchDB が提供する、スキーマなしのドキュメント指向データベース・モデルと呼ばれる新しいデータ保管方法について説明しています。
  • developerWorks Web development ゾーンでは、多種多様な Web ベースのソリューションを話題にした記事を揃えています。
  • Lift を入手してください。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=650393
ArticleTitle=Lift 2.0 の新機能
publish-date=03152011