endeworksでのWebAppの
作り方
株式会社endeworks
船木大郎
ENgineer DEsign WORKS
システム開発・コンサルティング
Webサイト作成・グラフィックデザイン
弊社代表
エンジニア募集
• ブラウザゲームの制作
• 各種システム開発
お手伝いいただけるPerlエンジニア募集!
モダンPerl先生に直接指導してもらえます
興味ある方いましたら、
taro@endeworks.jpまで
自己紹介
名前: 船木大郎
ハンドル: 33rpm
PAUSE ID: TAWAN
twitter: http://twitter.com/33rpm
アジェンダ
• WebAppを作る工程
• 開発のポリシー/コード規約
• pixisを紹介
• pixisの使い方
あらかじめ言っておきたいこと
特別なことは
なにもやっていません
コードの話の前に
WebAppを作る工程
• 開発
• テスト
• デプロイ
• 設置
開発環境
開発サーバと
いったものは用意していない
テスト
t/*以下のテストコードを書いてテスト
Test::FITesque
が最近の流行り
デプロイ
gitのマスターリポジトリから
git pull するだけ
デプロイツールといったものは
使用していない
設置
Apache+FCGI
FCGI
• daemontoolsでプロセス管理
– プロセス監視機能があるのでプロセスがおち
たまま気付かずにサービス停止ということが
ない
– 管理コマンドによる起動/停止/再起動が簡単
たとえば
• WebAppが依存するサービスが複数あって
それを同時に再起動したい場合
– FCGIプロセス & memcached といった場合
svc –t /etc/services/*
コードの話
WebAppの作り方
• Catalystを使用
• Mooseを使用
• APIモジュール
• キャッシングの仕方
• Registryモジュール
Model
CatalystのModelは使用しない
なぜModelを使用しないのか
• CatalystのModelは当たり前だけどCatalyst
依存
• ModelはWebという枠組みの外、たとえば
コマンドラインやワーカーからも呼び出
したいことが多い
• Catalyst::Model::DBIC::Schemaのような
ORMをControllerからそのまま呼び出すこ
とがない
ではどうするか?
Modelに相当するものは
MyApp::API::*
というネームスペースで作成
APIモジュールでは何を行うか
• 中身はORMにアプリケーションロジック
を加えて抽象化したモジュール
• キャッシングは全てここで管理する
キャッシングのポリシー
• ORMレベルでは行わない
• 人間が明示的に保存/削除を行う。
キャッシングの詳細
• テーブルのpkをkey、そのpkの行の全デー
タをvalueとしてkey value storageに
キャッシングをおこなう
• 検索結果などの複数行のデータをキャッ
シュしたい場合は全データを保存するの
ではなくpkの配列を保存する
DIコンテナは?
アプリケーション全体で共有される
インスタンスはRegistryというモジュールに
格納
Registryモジュール
メモリ上に
key value storeするだけの
singletonモジュール
その他
• Result定義を基にテーブルを作成する
• Formの作成はHTML::FormFuを使用
Result定義を基にDB作成
SQLからではなく
Resultモジュールの定義から
テーブルの作成や初期データ作成を行う
HTML::FormFu
• 今は使用しているけどいろいろ不満もあ
る
• all-in-one過ぎて生成されるhtmlに融通が
効かない
• Validatorはとてもよく出来ているのでレン
ダリングはさせないでValidatorだけ使うと
いうのが最近の流行り
具体的な実装であるpixis
http://github.com/lestrrat/pixis/tree/master
GitHubにて公開中
JPAサイトで利用されるほか
endeworksのプロダクトでも使用している
pixisとは
Webサービスや
SNSでありがちなアカウント管理や
メッセージング機能を
Catalystに加えたフレームワーク
Pixisの動作環境
• Catalyst 5.8依存
• あとはMakefile.PLを見て
Pixis::API::*
Member, Messageといった
Modelを抽象化して
アプリケーションロジックを
くわえたモジュール群が用意されています
APIモジュールの中身
• 共通で呼び出されているRoleが見つかる
with 'Pixis::API::Base::DBIC';
Pixis::API::Base::DBIC
• DBとキャッシュの橋渡しをするユーティ
リティメソッドを集めたRoleクラス
• MooseX::WithCacheを利用
MooseX::WithCache
• キャッシングのbackendを指定することで
cache_get, cache_setといったメソッドが
利用可能となるRoleクラス
use MooseX::WithCache;
with_cache 'cache' => (
backend => 'Cache::Memcached',
);
P::A::B::DBICのメソッド
• find()
• update()
• delete()
• search()
search()
my @rows = $rs->search($where, $attrs);
my @keys = $multi ?
map {
my $row = $_;
[ map { $row->$_ } @$pk ]
} @rows :
map { $_->$pk } @rows
;
return $self->load_multi(@keys);
}
Pixis::Registry
• getとsetを持っているだけのコンテナーク
ラス
• Singletonクラスなので、どんなコンテキ
ストからPixis::Registry->getと呼び出して
も同じインスタンスが得られる
• $c->model('foo')のようなもの
Pixis::Registryの使い方
• 配列の最後の値をvalue、それまでの値を
keyとして格納する
Pixis::Registry->set( schema =>
master => $schema
);
my $schema = Pixis::Registry
->get( schema => 'master' );
インスタンスの初期化
• 各プラグインの中でRegistryにインスタン
スをset していく
• デフォルトでCoreプラグインは呼ばれる
のでそれが参考になる
• Pixis::Plugin::Coreモジュール内のbefore
registerに渡された関数の中で初期化され
ている
pixisのプラグイン
• ある機能が必要とするAPI, Controller,
templateをまとめてloadする仕組み
• 今はほとんどCoreプラグインとして書か
れている
その他機能
• Widget機能
• I18N機能
Widget機能
• Widget TemplateとWidget Libararyを追加
することでTemplate内から下記のような
呼び出しが可能
<head>
[% run_widget('Head') %]
</head>
I18N機能
• I18N/[lang].po内で変換マップを記述して
おくことでTemplate内でこのような記述
が可能となる
<h2>[% loc("Basic Settings") %]</h2>
Pixisの使い方
現在公開されているPixisを使って
簡単にサービスを起動することができる
pixisをcheckout
$ git clone git@github.com:lestrrat/pixis.git
$ cd pixis
$ git branch roller
$ git checkout roller
$ git pull origin roller
アプリケーション作成
• Catalystのヘルパースクリプトがとりあえ
ずそのまま使える
$ catalyst.pl MyApp
pixisを読みこむ
• MyApp.pmを書き変える
package MyApp;
use Pixis::Web;
use namespace::clean -except => qw(meta);
__PACKAGE__->config( name => 'MyApp' );
__PACKAGE__->setup();
MyAppを起動
• MyApp → pixisの順でライブラリを読みこ
むようにして起動する
$ perl –Ilib –I[pixis_core_path]/lib 
script/myapp_server.pl -d
MyApp特有の実装を行う
• API, Controller, templateはMyAppに存在し
なければpixisで対応するファイルをloadす
る
• MyAppにファイルが存在していればそっ
ちが優先的にloadする
DBのSetup
script/pixis_setupdb.pl
というスクリプトを用意
中身は
Pixis::CLI::SetupDB
を呼び出しているだけ
pixis_setupdb.plの使い方
script/pixis_setupdb.pl
[--drop]
--dsn dsn
--username username
--password password
Pixisの今後
• 携帯対応
• 機能がCore Pluginに集まってるので分離
する?
• ヘルパースクリプト追加?
ご静聴ありがとう
ございました!

endeworksでのWebAppの作り方

Editor's Notes

  • #4 YAPC開催の主幹であるJPAの理事や、モダンPerl入門の著者である牧が代表をやっています。毎日僕のむかいでこの格好で鎮座しています。
  • #7 endeworksのWebApp開発ノウハウの最新版の反映といえるpixisのコードを紹介していきます。
  • #9 endeworksならではの裏技、必殺技みたいのは全く繰り出しません。普段あまり他の人がつくったCatalystアプリを見る機会もなさそうなので、あたりまえにやっていることを改めて話すことにも意味があるかなと 思ってます。比較できないことで不安に感じたりしていた人が、このスライドをみてああ、俺は標準サイズなんだなと安心してくれれば幸いです。
  • #11 コードの話をきくことはおおいけどそのまわりをとりまく環境については、あたりまえすぎてあらためて紹介されないので知りたい、という話をいただいたのでちょっと時間をつかって紹介したいと思います。
  • #12 各エンジニア、まあ二人ですがの端末でそれぞれ開発してます
  • #13 まあこれぐらい当たり前のことを話していきます
  • #14 バージョン管理も最近gitに移行して、二人でもうsubversionには戻りたくない、という話をしている。カピなんたらみたいのは使ってないです
  • #15 mod_perl, lightyという変遷があって今はこれでおちついています
  • #16 qmailで有名なdjbのソフトウェアでqmailと同様にdaemontoolsも癖があってとっつきにくいが、慣れるとなかなかわるくないです。
  • #17 ある決まったディレクトリ、この場合は、/etc/servicesに存在するディクトリがひとつのサービス/デーモン
  • #19 弊社での作り方のポリシーというかコード規約というかの中で特徴的な部分と思われるところを挙げます。MooseもCatalystもということで弊社ではCatalyst 5.8はプロダクトユースでがんがん使っています。
  • #20 APIモジュールというのはアプリケーションロジックをふくModelといったあつかい
  • #25 弊社で使うkey value storageはmemcachedです。pkの配列をとってきたら各pkについてまたデータをとってきます。