Flex⇔Perl連携 その3

帰省前に完結編間に合った!


前回の続き
見た目は変わらないんですが、サーバサイドをCatalystにしています*1
実は連携させるだけなら結構簡単に出来たのですが、
せっかくなので練習がてら「モダンPerl入門」に書かれていた構成に近づけようと頑張ってたら時間かかっちゃいました><
しかもうまく出来てるかわかんない><
モダンPerl入門 (CodeZine BOOKS)



クライアントサイド

前回使ったコードがほぼそのまま使えます!
http://github.com/toritori0318/Flex_Perl/tree/a61078e8ccd1d6bfe21326b2f37ae1d269a3043b/FlexToPerl_HTTPENGINE/client/src


…が、一点だけ修正が必要です。
サーバサイドではCatalyst::View::JSONJSONレスポンス作っているのですが、
これで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


あとは前回の手順でいうと、

  • テーブル作成(作成済みなら省略)
  • コネクション情報記述(Catalystの場合はコンフィグファイルを使うのが吉)
  • Empスキーマに「AsFdat」プラグイン追加

という所でしょうか。

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
JSONCatalyst::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)は切り離されてる…はず。
やっぱ手を動かすと全然勉強になるなー



動かす

まず、前回と同じようにサーバ側でCatalyst起動します。

$ script/amftest_web_server.pl


あとはFlexから検索実行すると、同じようにデータ取れてます!*3


今回使用したスクリプトgithubに置きました。(FlexToPerl_Catalyst
http://github.com/toritori0318/Flex_Perl/tree/master


バックエンドこの構成(Catalyst)でいけそうなので、
会社の案件これでやってみる!(`・ω・´)

*1:Flash Catalyst」ではなくて、PerlのWAFですよ!

*2:いや時間が…

*3:使いまわしw