how to pass arguments from an plack app to an mojolicious app enabled in builder?

徘徊边缘 提交于 2020-01-02 04:50:30

问题


given the example plack app using lots of middleware components and an mojolicious app enabled in builder (see below), how can i pass parameters from the app.psgi to Mojolicious without using the ugly %ENV hack shown? of cause passing an config is just an example, this could be any scalar/object.

app.psgi

use Plack::Builder;

$ENV{CONFIG} = {...};

builder {
    ...
    Mojolicious::Commands->start_app('MyApp');
};

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#');        
}

回答1:


This is an interesting question and is most easily tackled by looking at the source. In your example you rightly use

Mojolicious::Commands->start_app('MyApp');

Looking at the source shows that start_app is a rather simple wrapper:

sub start_app {
  my $self = shift;
  return Mojo::Server->new->build_app(shift)->start(@_);
}

It turns out that build_app is as well:

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};
}

returning a new instance of your app's class. The Mojolicious class's new function is more involved, but in the end, it just calls the familiar startup method and returns the instance.

This means that you cannot easily pass arguments to the startup method from your middleware wrapper, used in the standard way. I can think of two mechanisms to accomplish what you want to do: 1) write your own build_app function to replace the server's method but which passes arguments to $app->new (which would get passed to startup in turn) or 2) write your own start_app function which could call another startup-like function.

# in MyApp.pm

sub startup {
  ... # as before
}

sub after_startup {
  ... # your new code here,
      # or even most of what was in `startup` before
}

and

# app.psgi

builder {
  ...
  my $app = Mojo::Server->new->build_app(shift);
  $app->after_startup(@your_args_here);
  $app->start(@_);
}


来源:https://stackoverflow.com/questions/17594352/how-to-pass-arguments-from-an-plack-app-to-an-mojolicious-app-enabled-in-builder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!