1Plack::Builder(3)     User Contributed Perl Documentation    Plack::Builder(3)
2
3
4

NAME

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

SYNOPSIS

9         # in .psgi
10         use Plack::Builder;
11
12         my $app = sub { ... };
13
14         builder {
15             enable "Deflater";
16             enable "Session", store => "File";
17             enable "Debug", panels => [ qw(DBITrace Memory Timer) ];
18             enable "+My::Plack::Middleware";
19             $app;
20         };
21
22         # use URLMap
23
24         builder {
25             mount "/foo" => builder {
26                 enable "Foo";
27                 $app;
28             };
29
30             mount "/bar" => $app2;
31             mount "http://example.com/" => builder { $app3 };
32         };
33
34         # using OO interface
35         my $builder = Plack::Builder->new;
36         $builder->add_middleware('Foo', opt => 1);
37         $builder->add_middleware('Bar');
38         $builder->wrap($app);
39

DESCRIPTION

41       Plack::Builder gives you a quick domain specific language (DSL) to wrap
42       your application with Plack::Middleware subclasses. The middleware
43       you're trying to use should use Plack::Middleware as a base class to
44       use this DSL, inspired by Rack::Builder.
45
46       Whenever you call "enable" on any middleware, the middleware app is
47       pushed to the stack inside the builder, and then reversed when it
48       actually creates a wrapped application handler. "Plack::Middleware::"
49       is added as a prefix by default. So:
50
51         builder {
52             enable "Foo";
53             enable "Bar", opt => "val";
54             $app;
55         };
56
57       is syntactically equal to:
58
59         $app = Plack::Middleware::Bar->wrap($app, opt => "val");
60         $app = Plack::Middleware::Foo->wrap($app);
61
62       In other words, you're supposed to "enable" middleware from outer to
63       inner.
64

INLINE MIDDLEWARE

66       Plack::Builder allows you to code middleware inline using a nested code
67       reference.
68
69       If the first argument to "enable" is a code reference, it will be
70       passed an $app and should return another code reference which is a PSGI
71       application that consumes $env at runtime. So:
72
73         builder {
74             enable sub {
75                 my $app = shift;
76                 sub {
77                     my $env = shift;
78                     # do preprocessing
79                     my $res = $app->($env);
80                     # do postprocessing
81                     return $res;
82                 };
83             };
84             $app;
85         };
86
87       is equal to:
88
89         my $mw = sub {
90             my $app = shift;
91             sub { my $env = shift; $app->($env) };
92         };
93
94         $app = $mw->($app);
95

URLMap support

97       Plack::Builder has a native support for Plack::App::URLMap via the
98       "mount" method.
99
100         use Plack::Builder;
101         my $app = builder {
102             mount "/foo" => $app1;
103             mount "/bar" => builder {
104                 enable "Foo";
105                 $app2;
106             };
107         };
108
109       See Plack::App::URLMap's "map" method to see what they mean. With
110       "builder" you can't use "map" as a DSL, for the obvious reason :)
111
112       NOTE: Once you use "mount" in your builder code, you have to use
113       "mount" for all the paths, including the root path ("/"). You can't
114       have the default app in the last line of "builder" like:
115
116         my $app = sub {
117             my $env = shift;
118             ...
119         };
120
121         builder {
122             mount "/foo" => sub { ... };
123             $app; # THIS DOESN'T WORK
124         };
125
126       You'll get warnings saying that your mount configuration will be
127       ignored. Instead you should use "mount "/" => ..." in the last line to
128       set the default fallback app.
129
130         builder {
131             mount "/foo" => sub { ... };
132             mount "/" => $app;
133         }
134
135       Note that the "builder" DSL returns a whole new PSGI application, which
136       means
137
138       •   "builder { ... }" should normally be the last statement of a
139           ".psgi" file, because the return value of "builder" is the
140           application that is actually executed.
141
142       •   You can nest your "builder" blocks, mixed with "mount" statements
143           (see "URLMap support" above):
144
145             builder {
146                 mount "/foo" => builder {
147                     mount "/bar" => $app;
148                 }
149             }
150
151           will locate the $app under "/foo/bar", since the inner "builder"
152           block puts it under "/bar" and it results in a new PSGI application
153           which is located under "/foo" because of the outer "builder" block.
154

CONDITIONAL MIDDLEWARE SUPPORT

156       You can use "enable_if" to conditionally enable middleware based on the
157       runtime environment.
158
159         builder {
160             enable_if { $_[0]->{REMOTE_ADDR} eq '127.0.0.1' } 'StackTrace', force => 1;
161             $app;
162         };
163
164       See Plack::Middleware::Conditional for details.
165

OBJECT ORIENTED INTERFACE

167       Object oriented interface supports the same functionality with the DSL
168       version in a clearer interface, probably with more typing required.
169
170         # With mount
171         my $builder = Plack::Builder->new;
172         $builder->add_middleware('Foo', opt => 1);
173         $builder->mount('/foo' => $foo_app);
174         $builder->mount('/' => $root_app);
175         $builder->to_app;
176
177         # Nested builders. Equivalent to:
178         # builder {
179         #     mount '/foo' => builder {
180         #         enable 'Foo';
181         #         $app;
182         #     };
183         #     mount '/' => $app2;
184         # };
185         my $builder_out = Plack::Builder->new;
186         my $builder_in  = Plack::Builder->new;
187         $builder_in->add_middleware('Foo');
188         $builder_out->mount("/foo" => $builder_in->wrap($app));
189         $builder_out->mount("/" => $app2);
190         $builder_out->to_app;
191
192         # conditional. You can also directly use Plack::Middleware::Conditional
193         my $builder = Plack::Builder->new;
194         $builder->add_middleware_if(sub { $_[0]->{REMOTE_ADDR} eq '127.0.0.1' }, 'StackTrace');
195         $builder->wrap($app);
196

SEE ALSO

198       Plack::Middleware Plack::App::URLMap Plack::Middleware::Conditional
199
200
201
202perl v5.36.0                      2023-01-20                 Plack::Builder(3)
Impressum