同期との勉強会で発表した,Amon2の導入についての資料をまとめました.
- Amon2を初めて利用する人向け
- 単純なWebアプリを動かすところまでを説明します
- 完成品はこちら https://github.com/takanori/AmonSample
- (2014/02/16 追記) データベースにMySQL,O/Rマッパーに標準のTengを用います.
Amon2とは
Amon2とはPSGI/PlackベースのWeb Application Frameworkで,非常に薄く軽量でありながら高い拡張性を持ち,Web系企業の大規模なシステムでの使用実績があります.
公式サイトはこちら Amon2 - Web application framework for Rapid web development
Amon2のインストール
以下,Amon2のバージョンは5.16です.執筆時最新版の6.00でも正常に動作することを確認しています.
$ cpanm Amon2 Carton (略) $ amon2-setup.pl AmonSample -- Running flavor: Basic -- ... (中略) ... Setup script was done! You are ready to run the skelton. You need to install the dependencies by: > carton install And then, run your application server: > carton exec perl -Ilib script/amonsample-server
起動
carton install
はしばらく時間がかかります.
$ cd AmonSample $ carton install Installing modules using /Users/takanori/AmonSample/cpanfile Successfully installed Test-Harness-3.29 .. (中略) ... Complete! Modules were installed into /Users/takanori/AmonSample/local $ carton exec perl -Ilib script/amonsample-server AmonSample: http://127.0.0.1:5000/
ブラウザで確認
localhost:5000へアクセス
ディレクトリ構成
builder (Module::Build用設定) config データベースなどの設定ファイル db sqliteなどのデータベースファイル(mysqlなら使わない) lib perlファイル 主にこの中身をいじる local (Cartonがインストールした依存モジュール) script 起動スクリプト sql sqlファイル static js, css, image などの静的ファイル t テストファイル tmpl Xslateテンプレート xt (モジュールの作者専用テスト)
Router
# lib/AmonSample/Web/Dispatcher.pm package AmonSample::Web::Dispatcher; use strict; use warnings; use utf8; use Amon2::Web::Dispatcher::RouterBoom; any '/' => sub { my ($c) = @_; return $c->render('index.tx'); }; post '/account/logout' => sub { my ($c) = @_; $c->session->expire(); return $c->redirect('/'); }; 1;
Template
<!-- tmpl/index.tx --> : cascade "include/layout.tx" : override content -> { <h1>Hello, Amon2 world!</h1> : }
<!-- tmpl/include/layout.tx --> <!doctype html> <html> <head>...(中略)...</head> <body> <div class="container"> <div id="main"> <: block content -> { } :> </div> </div> </body> </html>
Webアプリを作ってみる
- 機能
- テキストを挿入できる
- 最新の1件を閲覧できる
- 構成
- MySQL
- Teng
変更する点を順番に見ていきましょう.
db設定
# config/development.pl +{ 'DBI' => [ 'dbi:mysql:amonsample', 'YourUserName', 'YourPassword', +{ mysql_enable_utf8 => 1 }, ], };
-- sql/mysql.sql CREATE TABLE IF NOT EXISTS memos ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, text TEXT ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# lib/AmonSample/DB/Schema.pm table { name 'memos'; pk 'id'; columns qw(id text); };
# root以外のユーザの場合,適切な権限が必要 $ mysqladmin -uYourUserName create amonsample -p $ mysql -uYourUserName amonsample < sql/mysql.sql -p
Model設定
# lib/AmonSample/DB.pm ...(略)... sub latest_text { my ($self) = @_; my ($row) = $self->search( 'memos', {}, { order_by => {'id' => 'DESC'}, limit => 1 } ); return $row->get_column('text') if ($row); } sub insert_memo { my ( $self, $text ) = @_; $self->insert( 'memos', { text => $text } ); } 1;
Router設定
# lib/AmonSample/Web/Dispatcher.pm ...(略)... get '/memo' => sub { my ($c) = @_; my $latest_text = $c->db->latest_text; $latest_text //= "No comment"; return $c->render( 'memo.tx', { latest_text => $latest_text } ); }; post '/memo/insert' => sub { my ($c) = @_; my $text = $c->req->param('text'); $c->db->insert_memo($text); return $c->redirect('/memo'); }; 1;
Template設定
<!-- tmpl/memo.tx --> : cascade "include/layout.tx" : override content -> { <h2><: $latest_text :></h2> <form method="post" action="<: uri_for('memo/insert') :>"> <textarea name="text" rows="3"></textarea> <input type="submit" value="Submit"> </form> : }
動作確認
localhost:5000/memo へアクセス