Flex⇔Perl連携 その3
帰省前に完結編間に合った!
前回の続き。
見た目は変わらないんですが、サーバサイドをCatalystにしています*1
実は連携させるだけなら結構簡単に出来たのですが、
せっかくなので練習がてら「モダンPerl入門」に書かれていた構成に近づけようと頑張ってたら時間かかっちゃいました><
しかもうまく出来てるかわかんない><
クライアントサイド
前回使ったコードがほぼそのまま使えます!
http://github.com/toritori0318/Flex_Perl/tree/a61078e8ccd1d6bfe21326b2f37ae1d269a3043b/FlexToPerl_HTTPENGINE/client/src
…が、一点だけ修正が必要です。
サーバサイドではCatalyst::View::JSONでJSONレスポンス作っているのですが、
これでJSON作ったとき、ルートに「response」というキーが付いてしまい、
このキーを取り除く方法がわからなかったのでクライアント側でそれを考慮する必要があります。
JSONClient.as
private function jsonResult( event:ResultEvent ) : void { var data:String = event.result.toString(); data = data.replace( /\s/g, '' ); var jd:JSONDecoder = new JSONDecoder( data ); // ここが追加箇所 var obj:Object = jd.getValue(); _view.dg.dataProvider = obj['response']; }
サーバサイド
とりあえず前準備
# Catalyst雛型作る catalyst.pl AmfTest::Web cd AmfTest-Web/ # ヘルパースクリプトでM/V/C雛型作る script/amftest_web_create.pl controller Amf script/amftest_web_create.pl model DB DBIC::Schema AmfTest::Web::Schema create=static dbi:Pg:dbname=test postgres script/amftest_web_create.pl view JSON JSON # サービスクラスとか手動で作る mkdir lib/AmfTest/Web/Service vi lib/AmfTest/Web/Model/Service.pm vi lib/AmfTest/Web/View/XML.pm
あとは前回の手順でいうと、
という所でしょうか。
FlashRemoting
Amfで連携する場合だけ、ちょっと特殊です。
typesterさんのCatalyst::Controller::FlashRemotingを使わせて頂きます。
AmfTest::Web::Controller::Amf
use strict; use warnings; use AmfTest::Web::Service::Emp; use base 'Catalyst::Controller::FlashRemoting'; use Data::Dumper; sub gateway :Local :AMFGateway { } sub echo :AMFMethod { my ($self, $c, $args) = @_; return $args; } sub sum :AMFMethod { my ($self, $c, $args) = @_; return List::Util::sum( @{ $args } ); } sub dump :AMFMethod { use YAML; warn Dump $_[0]; } sub list :AMFMethod { my ($self, $c, $args) = @_; my $hash = $$args[0]; my $api = AmfTest::Web::Service::Emp->new(); return $api->getEmp($c->model('DB::Emp'), $hash); }
ほぼpod通りですが。
あとRootはこんな感じ。
AmfTest::Web::Controller::Root(一部省略)
sub gateway : Local { my ( $self, $c ) = @_; $c->forward('/amf/gateway'); } sub json : Local { my ( $self, $c ) = @_; my $qq = cnv_hash( $c->req->uri->query ) if $c->req->uri->query; use AmfTest::Web::Service::Emp; my $api = AmfTest::Web::Service::Emp->new(); $c->stash->{response} = $api->getEmp( $c->model('DB::Emp'), $qq ); $c->forward( $c->view('JSON') ); } sub xml : Local { my ( $self, $c ) = @_; my $qq = cnv_hash( $c->req->uri->query ) if $c->req->uri->query; use AmfTest::Web::Service::Emp; my $api = AmfTest::Web::Service::Emp->new(); $c->stash->{xml} = $api->getEmp( $c->model('DB::Emp'), $qq ); $c->forward( $c->view('XML') ); }
もうなんか全然DRYじゃないですねw*2
JSONはCatalyst::View::JSONを、XMLは良いのが無かったので自作でView作りました。
Catalystの構成
ちょっと話はずれますが、Catalystの構成はこんな感じになってます
lib/ `-- AmfTest |-- Web | |-- Controller | |-- Model | | |-- DB.pm(DBIC) | | `-- Service.pm(Catalyst::Model::MultiAdaptor定義してるだけ) | |-- Schema(DBICで自動生成したもの) | |-- Schema.pm | |-- Service(いわゆるロジッククラス相当?) | `-- View `-- Web.pm
モダンPerl入門の最小構成みたいな感じ?
CatalystとModel(Service)は切り離されてる…はず。
やっぱ手を動かすと全然勉強になるなー