use*_*744 5 perl plack mojolicious
给出了使用大量中间件组件和在构建器中启用了一个mojolicious app的示例plack app(见下文),如何在不使用丑陋的%ENV hack的情况下将参数从app.psgi传递给Mojolicious?传递配置的原因只是一个例子,这可能是任何标量/对象.
app.psgi
use Plack::Builder;
$ENV{CONFIG} = {...};
builder {
...
Mojolicious::Commands->start_app('MyApp');
};
Run Code Online (Sandbox Code Playgroud)
MyApp.pm
package MyApp;
use Mojo::Base 'Mojolicious';
sub startup {
my $self = shift;
my $r = $self->routes;
$self->config( $ENV{CONFIG} );
$r->route('/')->to('home#');
}
Run Code Online (Sandbox Code Playgroud)
这是一个有趣的问题,通过查看源代码最容易解决。在你的例子中你正确使用
Mojolicious::Commands->start_app('MyApp');
Run Code Online (Sandbox Code Playgroud)
查看源代码表明这start_app
是一个相当简单的包装器:
sub start_app {
my $self = shift;
return Mojo::Server->new->build_app(shift)->start(@_);
}
Run Code Online (Sandbox Code Playgroud)
事实证明build_app
这也是:
sub build_app {
my ($self, $app) = @_;
local $ENV{MOJO_EXE};
return $app->new unless my $e = Mojo::Loader->new->load($app);
die ref $e ? $e : qq{Couldn't find application class "$app".\n};
}
Run Code Online (Sandbox Code Playgroud)
返回应用程序类的新实例。Mojolicious类的new
功能比较复杂,但最终只是调用熟悉的startup
方法并返回实例。
这意味着您无法轻松地将参数startup
从以标准方式使用的中间件包装器传递给该方法。我可以想到两种机制来完成你想做的事情:1)编写你自己的build_app
函数来替换服务器的方法,但将参数传递给$app->new
(依次传递给startup
)或2)编写你自己的start_app
函数,它可以调用另一个函数startup
类函数。
# in MyApp.pm
sub startup {
... # as before
}
sub after_startup {
... # your new code here,
# or even most of what was in `startup` before
}
Run Code Online (Sandbox Code Playgroud)
和
# app.psgi
builder {
...
my $app = Mojo::Server->new->build_app(shift);
$app->after_startup(@your_args_here);
$app->start(@_);
}
Run Code Online (Sandbox Code Playgroud)