Mojolicious、Mojolicious::Liteアプリをマウントする方法

Mojolicious、Mojolicious::Liteアプリをマウントする方法

プラグインとしては Mojolicious::Plugin::Mount  がある。短いコードなの読むと参考になる。

Mojoliciouアプリを埋め込む


追記:Mojolicious::Commandsを使う方法があるらしい。こっちの方が正統?

$app->routes->any( '/sub' )->detour(
    app => Mojolicious::Commands->start_app('SubApp') 
);

Mojolicious::Liteのアプリをマウントする方法は日本語だと Mojolicious::Guides::Routing に書いてある。

この方法を使ってMojoliciousアプリ(Liteではない)を埋め込む場合は、下記コードのようにMojo::Serverを使えば出来る。

# SubApp が Mojolicous::Liteの場合
$app->routes->any('/sub')->detour(app => SubApp::app());

# SubApp が Mojoliciousの場合
my $sub_app = Mojo::Server->new->build_app('SubApp');
$app->routes->any('/sub')->detour(app => $sub_app);

MyAppにSubAppを埋め込むだけの簡単なコードだとこんな感じ。

package MyApp;
use Mojo::Base 'Mojolicious';

# Route
sub startup {
    my $self = shift;
    my $app = $self->app;

    # Main route
    $self->routes->get('/')->to('foo#hello');

    # SubApp route
    my $sub_app = Mojo::Server->new->build_app('SubApp');
    $app->routes->any('/sub')->detour(app => $sub_app);
}

# Controller
package MyApp::Controller::Foo;
use Mojo::Base 'Mojolicious::Controller';

# Action
sub hello {
    my $self = shift;
    $self->render(text => 'Hello MyApp!');
}

# Sub App
package SubApp;
use Mojo::Base 'Mojolicious';

# Route
sub startup {
    my $self = shift;
    $self->routes->get('/')->to('foo#hello');
}

# Controller
package SubApp::Controller::Foo;
use Mojo::Base 'Mojolicious::Controller';

# Action
sub hello {
    my $self = shift;
    $self->render(text => 'Hello SubApp!');
}

# /    -> Hello MyApp!
# /sub -> Hello SubApp!

アプリケーションプラグイン

上記コードを使えば、Mojoliciousアプリでも自身を含めた再利用可能なプラグイン アプリケーションプラグイン のような事も出来るはず。

package Mojolicious::Plugin::EmbeddedSubApp;
use Mojo::Base 'Mojolicious::Plugin';

sub register {
    my ($self, $app) = @_;

    # ルートを追加
    my $sub_app = Mojo::Server->new->build_app('SubApp');
    $app->routes->any('/sub')->detour(app => $sub_app);
}

# Sub App
package SubApp;
use Mojo::Base 'Mojolicious';

# Route
sub startup {
    my $self = shift;
    $self->routes->get('/')->to('foo#hello');
}

# Controller
package SubApp::Controller::Foo;
use Mojo::Base 'Mojolicious::Controller';

# Action
sub hello {
    my $self = shift;
    $self->render(text => 'Hello SubApp!');
}

1;

アプリケーションでプラグインをロードする

package MyApp;
use Mojo::Base 'Mojolicious';

sub startup {
    my $self = shift;

    # プラグイン
    $self->plugin('EmbeddedSubApp');
}

1;

リンク