appengine-jrubyで簡単GAE/JRuby開発

少し前のエントリで、GAE/JRuby上でRackアプリを動かす手順を書きました。

このときの手順は、Java SDKをインストールして、GAE SDKをダウンロードして、jruby-complete.jarをコンパイルして…と、やや煩雑なものでした。この当時はおそらくこれが一般的な手法だったのではないかと思います。

しかし、今や時代は変わりました。今GAE/JRubyでRackアプリを作るのに必要な作業は、たったひとつのgemのインストールだけです。

有志によってGAE/JRuby上の開発を支援する"appengine-jruby"というプロジェクトが進められており、その成果として"google-appengine"というgemが開発されています。これを利用すれば、GAE SDKも、jruby-complete.jarも、JRuby-Rackも、何一つ自分で用意する必要はありません。*1更に、設定用のXMLファイルすら書く必要がありません。驚くほど簡単にGAE/JRuby上にRackアプリを構築できてしまいます。*2

実際にごくシンプルなRackアプリとSinatraアプリを作りつつ、どれほどお手軽にGAE/JRubyによる開発ができてしまうのかを実感してみたいと思います。

なお、以下の作業は全てCentOS 5.3上でRuby 1.9.1を使って行っています。またJDKyum経由でjava-1.6.0-openjdkパッケージとjava-1.6.0-openjdk-develパッケージをインストール済みです。

まず作ってみる

最初はお決まりの"Hello world"でいってみます。素のRackアプリです。以前のエントリでもまずこれを作成しましたので、その時の作業量と比較すると"google-appengine gem"の威力がよりわかりやすくなると思います。

gemのインストール

以下のコマンドを実行します。ここで実行するgemはCRubyのgemですので、気を付けてください。

$ gem install google-appengine
Successfully installed rack-1.0.0
Successfully installed appengine-rack-0.0.2
Successfully installed appengine-sdk-1.2.2
Successfully installed appengine-jruby-jars-0.0.2
Successfully installed appengine-tools-0.0.2
Successfully installed google-appengine-0.0.2
6 gems installed

いくつか依存関係にあるgemが一緒にインストールされます。GAE SDKなど必要なものは全てこれらの中に含まれています。

アプリケーションの作成

ではアプリケーションの作成に取り掛かります。まず適当にディレクトリを掘ります。

$ mkdir hello
$ cd hello

次に、"config.ru"という名前*3でアプリケーションの設定ファイル兼ソースファイルを作成します。

  • config.ru
require 'appengine-rack'
AppEngine::Rack.configure_app(
  :application => 'application-id', # Replace your application id.
  :version => 1                     # Replace your application version.
)
run lambda { Rack::Response.new('Hello world!') }

"*.ru"というファイルはrackup用の設定ファイルです。rackupというのはrackのミドルウェアを簡単に扱うためのユーティリティですが、その辺りの詳しいことは以下のページ等を参照してください。

コードの中身は、だいたいパッと見て意味はわかるかと思います。設定として最低限必要な「アプリケーションID」と「バージョン番号」をセットし、runメソッドに渡すブロック*4内でアプリケーションの処理本体を記述しています。ここでは単に"Hello world!"を返しているだけです。

開発サーバの起動

では開発サーバを起動して、アプリケーションの動作を確認してみます。

まだ他の設定ファイルもライブラリも何も用意していない?大丈夫です、その辺は全て"google-appengine gem"のユーティリティ群がなんとかしてくれます。

$ dev_appserver.rb .

外からアクセスする場合は、次のようにアクセスを受け付けるアドレスの範囲を指定します。この辺りはGAE SDKに含まれるdev_appserver.shと同じです。

$ dev_appserver.rb --address=0.0.0.0 .

コマンド実行後、つらつらとログが表示されていきますが、このタイミングでプロジェクトに必要なライブラリをコピーし、設定ファイルを自動生成しています。この辺りの初期化処理は、関係する部分に変更が無ければ次回以降はスキップされます。

しばらく待つと以下のメッセージが表示され、アクセス可能な状態になります。実際にブラウザでアクセスして動作を確認してみてください。

The server is running at http://localhost:8080/
GAEへのアップロード

最後に、本番環境で動かしてみます。

アップロード前に、先程の"config.ru"内のアプリケーションIDとバージョン番号が正しいことを確認してください。

$ appcfg.rb update .

途中でメールアドレスとパスワードを聞かれますので入力します。

Update completed successfully.
Success.
Cleaning up temporary files...

上記のメッセージが出力されたら無事成功です。GAE上のアプリケーションにアクセスして動作を確認してみてください。

ちなみに、開発サーバを一度も立ち上げずにGAEへアップロードした場合でも、アップロード前にちゃんと必要なライブラリや設定ファイルが生成されるので問題ありません。あまり無いケースだとは思いますが。

手順のまとめ

以上で"Hello world"アプリは完成です。

手順をおさらいすると、

  1. gemのインストール(2回目以降は不要)
  2. "config.ru"の作成
  3. 開発サーバの起動(スキップ可)
  4. アップロード

だけです。以前の、自力でGAE/JRuby環境を用意していたころと比べると、驚くほど簡単になりました。

Sinatraアプリを作ってみる

とは言え、素のRackアプリで色々やるのは何かとキツイので、Sinatraを導入するところくらいまではやっておこうと思います。

Sinatraはとてもシンプルで扱いやすいWebアプリケーションフレームワークです。公式には“最小労力で手早くウェブアプリケーションを作成するためのDSL”だと説明されています。

シンプルですが、Webアプリケーションを書くのに必要十分な機能は揃っています。GAE/JRubyで軽めのWebアプリをサクッと作りたい場合はRailsより適しているかもしれません。

Sinatraについては以下のページ等を参考にしてください。

Sinatraのインストール

Sinatraは一緒にGAEにアップロードすることになりますので、プロジェクトのディレクトリ内にインストールします。

これも以前はgemコマンドの-iオプション等を使っていましたが、"google-appengine gem"に付いてくるappcfg.rbコマンド経由でgemの管理ができるようになりました。

以下のように適当にディレクトリを作成後、その中でインストールを行います。

$ mkdir greeting
$ cd greeting
$ appcfg.rb gem install sinatra
Successfully installed rack-1.0.0
Successfully installed sinatra-0.9.4
2 gems installed

プロジェクトディレクトリ内にインストールしていますので、別のプロジェクトを作成した際はその都度インストールする必要があります。

設定ファイルの作成

"config.ru"を作成します。今回はアプリケーション本体は別ファイルにしますので、"config.ru"は純粋に設定ファイルの役割を果たします。

  • config.ru
require 'appengine-rack'
require 'application'
AppEngine::Rack.configure_app(
  :application => 'application-id', # Replace your application id.
  :version => 1                     # Replace your application version.
)
run Sinatra::Application

2行目でrequireしているのがアプリケーション本体のファイルです。他は特に説明は要らないかと思います。

アプリケーションファイルの作成

Sinatraが動くことが確認できればいいので、パスに指定した文字列に合わせてあいさつを変えるだけの簡単なアプリケーションにします。“Hello world レベル2”といった感じです。

  • application.rb
require 'rubygems'
require 'sinatra'

get '/'        do 'Hello world!'  end
get '/morning' do 'Good morning.' end
get '/evening' do 'Good evening.' end
get '/night'   do 'Good night.'   end
get '/bye'     do 'Good bye.'     end

これも特に説明は要らないかと思います。

開発サーバの起動&アップロード

これ以降は基本的に先程と同じ作業です。

$ dev_appserver.rb --address=0.0.0.0 .

で動作を確認し、

$ appcfg.rb update .

でGAEへアップロードします。

次のステップへ

appengine-jrubyに含まれるのはGAE/JRubyアプリの作成支援機能だけではありません。

以下のドキュメントを見てもわかる通り、DatastoreにURLFetchなど、GAEに用意されている一通りのサービスを利用するためのAPIが揃っています。

まだAPIの詳細は確認していませんが、おそらくこれ一つでそれなりにきちんとしたWebアプリケーションは作れてしまうのではないでしょうか。もうJavaAPIを意識する必要も無さそうです。

これまでJavaの低レベルAPIを直接触って色々やってきましたが、せっかくなので方針を転換し、appengine-jrubyを使い倒す方向で色々弄ってみようと思います。

とりあえずはappengine-jrubyTwitter botでも作ってみようかな?*5

*1:さすがにJava環境は用意しなければいけませんが。

*2:正直な話、私はそのあまりの簡単さに軽く感動すら覚えてしまいました。

*3:固定です

*4:正確には手続きオブジェクト

*5:またそれか!