GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages


Manual Reference Pages  -  PLACK::BUILDER (3)

.ds Aq ’

NAME

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

CONTENTS

SYNOPSIS



  # in .psgi
  use Plack::Builder;

  my $app = sub { ... };

  builder {
      enable "Deflater";
      enable "Session", store => "File";
      enable "Debug", panels => [ qw(DBITrace Memory Timer) ];
      enable "+My::Plack::Middleware";
      $app;
  };

  # use URLMap

  builder {
      mount "/foo" => builder {
          enable "Foo";
          $app;
      };

      mount "/bar" => $app2;
      mount "http://example.com/" => builder { $app3 };
  };

  # using OO interface
  my $builder = Plack::Builder->new;
  $builder->add_middleware(Foo, opt => 1);
  $builder->add_middleware(Bar);
  $builder->wrap($app);



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 enable 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. "Plack::Middleware::" is added as a prefix by default. So:



  builder {
      enable "Foo";
      enable "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 enable middleware from outer to inner.

INLINE MIDDLEWARE

Plack::Builder allows you to code middleware inline using a nested code reference.

If the first argument to enable is a code reference, it will be passed an $app and should return another code reference which is a PSGI application that consumes $env at runtime. So:



  builder {
      enable sub {
          my $app = shift;
          sub {
              my $env = shift;
              # do preprocessing
              my $res = $app->($env);
              # do postprocessing
              return $res;
          };
      };
      $app;
  };



is equal to:



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

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



URLMap support

Plack::Builder has a native support for Plack::App::URLMap via the mount method.



  use Plack::Builder;
  my $app = builder {
      mount "/foo" => $app1;
      mount "/bar" => builder {
          enable "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 :)

<B>NOTEB>: 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:



  my $app = sub {
      my $env = shift;
      ...
  };

  builder {
      mount "/foo" => sub { ... };
      $app; # THIS DOESNT 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.



  builder {
      mount "/foo" => sub { ... };
      mount "/" => $app;
  }



Note that the builder DSL returns a whole new PSGI application, which means
o builder { ... } should normally the last statement of a .psgi file, because the return value of builder is the application that is actually executed.
o You can nest your builder blocks, mixed with mount statements (see URLMap support above):



  builder {
      mount "/foo" => builder {
          mount "/bar" => $app;
      }
  }



will locate the $app under /foo/bar, since the inner builder block puts it under /bar and it results in a new PSGI application which is located under /foo because of the outer builder block.

CONDITIONAL MIDDLEWARE SUPPORT

You can use enable_if to conditionally enable middleware based on the runtime environment.



  builder {
      enable_if { $_[0]->{REMOTE_ADDR} eq 127.0.0.1 } StackTrace, force => 1;
      $app;
  };



See Plack::Middleware::Conditional for details.

OBJECT ORIENTED INTERFACE

Object oriented interface supports the same functionality with the DSL version in a clearer interface, probably with more typing required.



  # With mount
  my $builder = Plack::Builder->new;
  $builder->add_middleware(Foo, opt => 1);
  $builder->mount(/foo => $foo_app);
  $builder->mount(/ => $root_app);
  $builder->to_app;

  # Nested builders. Equivalent to:
  # builder {
  #     mount /foo => builder {
  #         enable Foo;
  #         $app;
  #     };
  #     mount / => $app2;
  # };
  my $builder_out = Plack::Builder->new;
  my $builder_in  = Plack::Builder->new;
  $builder_in->add_middleware(Foo);
  $builder_out->mount("/foo" => $builder_in->wrap($app));
  $builder_out->mount("/" => $app2);
  $builder_out->to_app;

  # conditional. You can also directly use Plack::Middleware::Conditional
  my $builder = Plack::Builder->new;
  $builder->add_middleware_if(sub { $_[0]->{REMOTE_ADDR} eq 127.0.0.1 }, StackTrace);
  $builder->wrap($app);



SEE ALSO

Plack::Middleware Plack::App::URLMap Plack::Middleware::Conditional
Search for    or go to Top of page |  Section 3 |  Main Index


perl v5.20.3 PLACK::BUILDER (3) 2015-06-03

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.