Plack::Builder.3pm

Langue: en

Version: 2010-05-20 (ubuntu - 24/10/10)

Section: 3 (Bibliothèques de fonctions)

NAME

Plack::Builder - OO and DSL to enable Plack Middlewares

SYNOPSIS

   # in .psgi
   use Plack::Builder;
 
   my $app = sub { ... };
 
   builder {
       enable "Plack::Middleware::Foo";
       enable "Plack::Middleware::Bar", opt => "val";
       enable "Plack::Middleware::Baz";
       enable sub {
           my $app = shift;
           sub {
               my $env = shift;
               $app->($env);
           };
       };
       $app;
   };
 
   # use URLMap
 
   builder {
       mount "/foo" => builder {
           enable "Plack::Middleware::Foo";
           $app;
       };
 
       mount "/bar" => $app2;
       mount "http://example.com/" => builder { $app3 };
   };
 
 

DESCRIPTION

Plack::Builder gives you a quick domain specific language (DSL) to wrap your application with Plack::Middleware subclasses. The middleware you're trying to use should use Plack::Middleware as a base class to use this DSL, inspired by Rack::Builder.

Whenever you call "add" on any middleware, the middleware app is pushed to the stack inside the builder, and then reversed when it actually creates a wrapped application handler, so:

   builder {
       enable "Plack::Middleware::Foo";
       enable "Plack::Middleware::Bar", opt => "val";
       $app;
   };
 
 

is syntactically equal to:

   $app = Plack::Middleware::Bar->wrap($app, opt => "val");
   $app = Plack::Middleware::Foo->wrap($app);
 
 

In other words, you're supposed to "add" middleware from outer to inner.

Additionally, you can call "enable" with a coderef, which would take $app and returns a another psgi-app which consumes $env in runtime. So:

   my $mw = sub {
       my $app = shift;
       sub { my $env = shift; $app->($env) };
   };
 
   builder {
       enable $mw;
       $app;
   };
 
 

is syntactically equal to:

   $app = $mw->($app);
 
 

URLMap support

Plack::Builder has a native support for Plack::App::URLMap with "mount" method.
   use Plack::Builder;
   my $app = builder {
       mount "/foo" => $app1;
       mount "/bar" => builder {
           enable "Plack::Middleware::Foo";
           $app2;
       };
   };
 
 

See Plack::App::URLMap's "map" method to see what they mean. With builder you can't use "map" as a DSL, for the obvious reason :)

Note: Once you use "mount" in your builder code, you have to use "mount" for all the paths, including the root path ("/"). You can't have the default app in the last line of "builder" like:

   builder {
       mount "/foo" => sub { ... };
       sub {
           my $env = shift; # THIS DOESN'T WORK
       };
   };
 
 

You'll get warnings saying that your mount configuration will be ignored. Instead you should use "mount "/" => ..." in the last line to set the default fallback app.

CONDITIONAL MIDDLEWARE SUPPORT

You can use "enable_if" to conditionally enable middleware based on the runtime environment. See Plack::Middleware::Conditional for details.

SEE ALSO

Plack::Middleware Plack::App::URLMap Plack::Middleware::Conditional