pirka-slim3 0.1.0 リリース

pirka-slim3はテンプレートエンジン pirkaengine をGAEで利用する為のモジュールです。slim3を使ってJSPを利用したくない人にオススメです。

特徴

pirkaengineの最大の特徴は、JRE以外に依存ライブラリがない点です。したがって、GAEを扱う上での最大の問題の1つになるスピンアップ時のクラスロードを最小限に抑えることができます。これはJSPを使う場合に発生するJasperのロードも発生しないという事です。
テンプレート本体は、XHTMLをベースとしループや制御構文はXMLの属性として定義します。これはデザイナ向けにデザインされたフォーマットですが、プログラマでも十分に活用できるように外部定義関数を呼べるなどの機能を持ちます。ソーシャルアプリ等でデザイナと協業する場合には使いやすいでしょう。
pirka-slim3では、キャッシュ機能をDatastoreまたはMemcacheとすることで、さらにパフォーマンスを考慮した形と鳴っています。勿論、ローカル環境ではテンプレートの変更は即時に反映されるため、開発のテンポも乱しません。
その他の機能についてはドキュメントを参照ください。

サンプル

テンプレートのサンプルです。ソース一式はこちら
titleと商品の一覧をループしています。

<html xmlns:prk="http://pirkaengine.org/" >
<head>
  <title>${title}</title>
</head>
<body>
  <h1>${title}</h1>
  <table>
    <tr>
      <th>Name</th>
      <th>Price</th>
    </tr>
    <tr prk:for="idx, item in list">
      <td>${idx}.<a href="view.html" prk:attr.href="view/${item.id}" >${item.name}</a></td>
      <td>${item.price}</td>
    </tr>
  </table>
</body>
</html>

aタグのhref属性は商品のidを付与したリンクになります。listはItemクラスのリストですが、Itemクラスのpublicフィールドやgetterメソッドで取得できる項目が表示される事になります。

Slim3のみを使ったコントローラ側のサンプルです。

import org.pirkaengine.slim3.PirkaController;
import org.slim3.controller.Navigation;

public class IndexController extends PirkaController {
    public Navigation run() throws Exception {
        List<Item> list = new ArrayList<Item>();
        list.add(new Item(1, "Book", 3200));
        list.add(new Item(2, "Game", 7800));
        list.add(new Item(3, "Music Video", 2800));
        viewModel("list", list);
        viewModel("title", "Wish List");
        return render("index.html");
    }
}

PirkaControllerは便利なメソッドを提供しているだけなので、ベタに書けば次のようになります。

import org.pirkaengine.slim3.PirkaRenderer;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;

public class IndexController extends Controller {
    public Navigation run() throws Exception {
        List<Item> list = new ArrayList<Item>();
        list.add(new Item(1, "Book", 3200));
        list.add(new Item(2, "Game", 7800));
        list.add(new Item(3, "Music Video", 2800));
        Map<String, Object> viewModel = new HashMap<String, Object>();
        viewModel.put("list", list);
        viewModel.put("title", "Wish List");
        return PirkaRenderer.render(request, response, "index.html", viewModel);
    }
}

Scenic3を使う事もできます。

import org.pirkaengine.slim3.PirkaPage;
import org.slim3.controller.Navigation;

@Page("/")
public class FrontPage extends PirkaPage {
    @Default
    public Navigation index() throws Exception {
        List<Item> list = new ArrayList<Item>();
        list.add(new Item(1, "Book", 3200));
        list.add(new Item(2, "Game", 7800));
        list.add(new Item(3, "Music Video", 2800));
        viewModel("list", list);
        viewModel("title", "Wish List");
        return render("index.html");
    }
}

設定

初期化時に org.pirkaengine.slim3.PirkaengineOnSlim3#initを呼び出してください。
ServletContextListenerを用意しているので、web.xmlにlistenerを追加するだけでも構いません。

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
  <listener>
    <listener-class>org.pirkaengine.slim3.PirkaEngineInitalizer</listener-class>
  </listener>
</web-app>

デフォルトはキャッシュにmemcaheを使いますが、Datastoreを使う場合はappengine-web.xmlにパラメータを追加します。

<system-properties>
  <property name="org.pirkaengine.cache.mode" value="datastore" />
</system-properties>

パフォーマンス

JSPに比べてレンダリングはやや遅い程度ですが、気にするほどではありません。JSPを利用する場合のスピンアップのオーバヘッド(300〜500ms程度)を抑えられることのトレードオフとしましょう。
最大の難点はGAEのQuotaを消費することです。個々の案件によって数値も変わってくると思うので、データが揃ってみたら公開してみたいですね。