1Mojolicious::Guides::RoUusteirngC(o3n)tributed Perl DocuMmoejnotlaitciioonus::Guides::Routing(3)
2
3
4
6 Mojolicious::Guides::Routing - Routing
7
9 This document contains a simple and fun introduction to the Mojolicious
10 router and its underlying concepts.
11
13 Essentials every Mojolicious developer should know.
14
15 Dispatcher
16 The foundation of every web framework is a tiny black box connecting
17 incoming requests with code generating the appropriate response.
18
19 GET /user/show/1 -> $self->render(text => 'Sebastian!');
20
21 This black box is usually called a dispatcher. There are many
22 implementations using different strategies to establish these
23 connections, but pretty much all are based around mapping the requests
24 path to some kind of response generator.
25
26 /user/show/1 -> $self->render(text => 'Sebastian!');
27 /user/show/2 -> $self->render(text => 'Sara!');
28 /user/show/3 -> $self->render(text => 'Baerbel!');
29 /user/show/4 -> $self->render(text => 'Wolfgang!');
30
31 While it is very well possible to make all these connections static, it
32 is also rather inefficient. Thats why regular expressions are commonly
33 used to make the dispatch process more dynamic.
34
35 qr|/user/show/(\d+)| -> $self->render(text => $users{$1});
36
37 Modern dispatchers have pretty much everything HTTP has to offer at
38 their disposal and can use many more variables than just the request
39 path, such as request method and headers like "Host", "User-Agent" and
40 "Accept".
41
42 GET /user/show/23 HTTP/1.1
43 Host: mojolicious.org
44 User-Agent: Mozilla/5.0 (compatible; Mojolicious; Perl)
45 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
46
47 Routes
48 While regular expressions are quite powerful they also tend to be
49 unpleasant to look at and are generally overkill for ordinary path
50 matching.
51
52 qr|/user/show/(\d+)| -> $self->render(text => $users{$1});
53
54 This is where routes come into play, they have been designed from the
55 ground up to represent paths with placeholders.
56
57 /user/show/:id -> $self->render(text => $users{$id});
58
59 The only difference between a static path and the route above is the
60 ":id" placeholder. One or more placeholders can be anywhere in the
61 route.
62
63 /user/:action/:id
64
65 A fundamental concept of the Mojolicious router is that extracted
66 placeholder values are turned into a hash.
67
68 /user/show/23 -> /user/:action/:id -> {action => 'show', id => 23}
69
70 This hash is basically the center of every Mojolicious application, you
71 will learn more about this later on. Internally routes get compiled to
72 regular expressions, so you can get the best of both worlds with a
73 little bit of experience.
74
75 /user/show/:id -> qr/(?-xism:^\/user\/show/([^\/\.]+))/
76
77 Reversibility
78 One more huge advantage routes have over regular expressions is that
79 they are easily reversible, extracted placeholders can be turned back
80 into a path at any time.
81
82 /sebastian -> /:name -> {name => 'sebastian'}
83 {name => 'sebastian'} -> /:name -> /sebastian
84
85 Generic Placeholders
86 Generic placeholders are the simplest form of placeholders and match
87 all characters except "/" and ".".
88
89 /hello -> /:name/hello -> undef
90 /sebastian/23/hello -> /:name/hello -> undef
91 /sebastian.23/hello -> /:name/hello -> undef
92 /sebastian/hello -> /:name/hello -> {name => 'sebastian'}
93 /sebastian23/hello -> /:name/hello -> {name => 'sebastian23'}
94 /sebastian 23/hello -> /:name/hello -> {name => 'sebastian 23'}
95
96 A generic placeholder can be surrounded by backets to separate it from
97 the surrounding text.
98
99 /hello -> /(:name)hello -> undef
100 /sebastian/23hello -> /(:name)hello -> undef
101 /sebastian.23hello -> /(:name)hello -> undef
102 /sebastianhello -> /(:name)hello -> {name => 'sebastian'}
103 /sebastian23hello -> /(:name)hello -> {name => 'sebastian23'}
104 /sebastian 23hello -> /(:name)hello -> {name => 'sebastian 23'}
105
106 Relaxed Placeholders
107 Relaxed placeholders are very similar to generic placeholders but
108 always require brackets and match all characters except "/".
109
110 /hello -> /(.name)/hello -> undef
111 /sebastian/23/hello -> /(.name)/hello -> undef
112 /sebastian.23/hello -> /(.name)/hello -> {name => 'sebastian.23'}
113 /sebastian/hello -> /(.name)/hello -> {name => 'sebastian'}
114 /sebastian23/hello -> /(.name)/hello -> {name => 'sebastian23'}
115 /sebastian 23/hello -> /(.name)/hello -> {name => 'sebastian 23'}
116
117 Wildcard Placeholders
118 Wildcard placeholders are just like relaxed placeholders but match
119 absolutely everything.
120
121 /hello -> /(*name)/hello -> undef
122 /sebastian/23/hello -> /(*name)/hello -> {name => 'sebastian/23'}
123 /sebastian.23/hello -> /(*name)/hello -> {name => 'sebastian.23'}
124 /sebastian/hello -> /(*name)/hello -> {name => 'sebastian'}
125 /sebastian23/hello -> /(*name)/hello -> {name => 'sebastian23'}
126 /sebastian 23/hello -> /(*name)/hello -> {name => 'sebastian 23'}
127
129 Most commonly used features every Mojolicious developer should know
130 about.
131
132 Minimal Route
133 Every Mojolicious application has a router object you can use to
134 generate routes structures.
135
136 # Application
137 package MyApp;
138 use base 'Mojolicious';
139
140 sub startup {
141 my $self = shift;
142
143 # Router
144 my $r = $self->routes;
145
146 # Route
147 $r->route('/welcome')->to(controller => 'foo', action => 'welcome');
148 }
149
150 1;
151
152 The minimal static route above will load and instantiate the class
153 "MyApp::Foo" and call its "welcome" method.
154
155 # Controller
156 package MyApp::Foo;
157 use base 'Mojolicious::Controller';
158
159 # Action
160 sub welcome {
161 my $self = shift;
162
163 # Render response
164 $self->render(text => 'Hello there!');
165 }
166
167 1;
168
169 Routes are usually configured in the "startup" method of the
170 application class, but the router can be accessed from everywhere (even
171 at runtime).
172
173 Routing Destination
174 After you start a new route with the "route" method you can also give
175 it a destination in the form of a hash using the chained "to" method.
176
177 # /welcome -> {controller => 'foo', action => 'welcome'}
178 $r->route('/welcome')->to(controller => 'foo', action => 'welcome');
179
180 Now if the route matches an incoming request it will use the content of
181 this hash to try and find appropriate code to generate a response.
182
183 Stash
184 The generated hash of a matching route is actually the center of the
185 whole Mojolicious request cycle. We call it the stash, and it is
186 basically a global namespace that persists until a response has been
187 generated.
188
189 # /bye -> {controller => 'foo', action => 'bye', mymessage => 'Bye!'}
190 $r->route('/bye')
191 ->to(controller => 'foo', action => 'bye', mymessage => 'Bye!');
192
193 There are a few stash values with special meaning, such as "controller"
194 and "action", but you can generally fill it with whatever data you need
195 to generate a response. Once dispatched the whole stash content can be
196 changed at any time.
197
198 sub bye {
199 my $self = shift;
200
201 # Get message from stash
202 my $message = $self->stash('mymessage');
203
204 # Change message in stash
205 $self->stash(mymessage => 'Welcome!');
206 }
207
208 Special Stash Values ("controller" and "action")
209 When the dispatcher sees "controller" and "action" values in the stash
210 it will always try to turn them into a class and method to dispatch to.
211 The "controller" value gets camelized and prefixed with a "namespace"
212 (defaulting to the applications class) while the action value is not
213 changed at all, because of this both values are case sensitive.
214
215 # Application
216 package MyApp;
217 use base 'Mojolicious';
218
219 sub startup {
220 my $self = shift;
221
222 # Router
223 my $r = $self->routes;
224
225 # /bye -> {controller => 'foo', action => 'bye'} -> MyApp::Foo->bye
226 $r->route('/bye')->to(controller => 'foo', action => 'bye');
227 }
228
229 1;
230
231 # Controller
232 package MyApp::Foo;
233 use base 'Mojolicious::Controller';
234
235 # Action
236 sub bye {
237 my $self = shift;
238
239 # Render response
240 $self->render(text => 'Good bye!');
241 }
242
243 1;
244
245 Controller classes are perfect for organizing code in larger projects.
246 There are more dispatch strategies, but because controllers are the
247 most commonly used ones they also got a special shortcut in the form of
248 "controller#action".
249
250 # /bye -> {controller => 'foo', action => 'bye', mymessage => 'Bye!'}
251 $r->route('/bye')->to('foo#bye', mymessage => 'Bye!');
252
253 During camelization "-" gets replaced with "::", this allows multi
254 level "controller" hierarchies.
255
256 # / -> {controller => 'foo-bar', action => 'hi'} -> MyApp::Foo::Bar->hi
257 $r->route('/')->to('foo-bar#hi');
258
259 Route To Class ("namespace")
260 From time to time you might want to dispatch to a whole different
261 "namespace".
262
263 # /bye -> MyApp::Controller::Foo->bye
264 $r->route('/bye')
265 ->to(namespace => 'MyApp::Controller::Foo', action => 'bye');
266
267 The "controller" is always appended to the "namespace" if available.
268
269 # /bye -> MyApp::Controller::Foo->bye
270 $r->route('/bye')->to('foo#bye', namespace => 'MyApp::Controller');
271
272 You can also change the default namespace for all routes.
273
274 $r->namespace('MyApp::Controller');
275
276 Route To Callback ("cb")
277 You can use the "cb" stash value to bypass controllers and execute a
278 callback instead.
279
280 $r->route('/bye')->to(cb => sub {
281 my $self = shift;
282 $self->render(text => 'Good bye!');
283 });
284
285 This technique is the foundation of Mojolicious::Lite, you can learn
286 more about it from the included tutorial.
287
288 Formats
289 File extensions like ".html" and ".txt" at the end of a route are
290 automatically detected and stored in the stash value "format".
291
292 # /foo -> {controller => 'foo', action => 'bar'}
293 # /foo.html -> {controller => 'foo', action => 'bar', format => 'html'}
294 # /foo.txt -> {controller => 'foo', action => 'bar', format => 'txt'}
295 $r->route('/foo')->to(controller => 'foo', action => 'bar');
296
297 This for example allows multiple templates for different formats to
298 share the same code.
299
300 Placeholders And Destinations
301 Extracted placeholder values will simply redefine older stash values if
302 they already exist.
303
304 # /bye -> {controller => 'foo', action => 'bar', mymessage => 'bye'}
305 # /hey -> {controller => 'foo', action => 'bar', mymessage => 'hey'}
306 $r->route('/:mymessage')
307 ->to(controller => 'foo', action => 'bar', mymessage => 'hi');
308
309 One more interesting effect, if a placeholder is at the end of a route
310 and there is already a stash value of the same name present, it
311 automatically becomes optional.
312
313 # / -> {controller => 'foo', action => 'bar', mymessage => 'hi'}
314 $r->route('/:mymessage')
315 ->to(controller => 'foo', action => 'bar', mymessage => 'hi');
316
317 This is also the case if multiple placeholders are right after another
318 and not separated by other characters than "/".
319
320 # / -> {controller => 'foo', action => 'bar'}
321 # /users -> {controller => 'users', action => 'bar'}
322 # /users/list -> {controller => 'users', action => 'list'}
323 $r->route('/:controller/:action')
324 ->to(controller => 'foo', action => 'bar');
325
326 Special stash values like "controller" and "action" can also be
327 placeholders, this allows for extremely flexible routes constructs.
328
329 Named Routes
330 Naming your routes will allow backreferencing in many kinds of helpers
331 throughout the whole framework.
332
333 # /foo/abc -> {controller => 'foo', action => 'bar', name => 'abc'}
334 $r->route('/foo/:name')->name('test')
335 ->to(controller => 'foo', action => 'bar');
336
337 # Generate URL "/foo/abc" for route "test"
338 $self->url_for('test');
339
340 # Generate URL "/foo/sebastian" for route "test"
341 $self->url_for('test', name => 'sebastian');
342
343 The value "*" means that the name is simply equal to the route without
344 non-word characters.
345
346 # /foo/bar ("foobar")
347 $r->route('/foo/bar')->to('test#stuff')->name('*');
348
349 # Generate URL "/foo/bar"
350 $self->url_for('foobar');
351
352 HTTP Methods
353 The "via" method of the route object allows only specific HTTP methods
354 to pass.
355
356 # GET /bye -> {controller => 'foo', action => 'bye'}
357 # POST /bye -> undef
358 # DELETE /bye -> undef
359 $r->route('/bye')->via('get')->to(controller => 'foo', action => 'bye');
360
361 # GET /bye -> {controller => 'foo', action => 'bye'}
362 # POST /bye -> {controller => 'foo', action => 'bye'}
363 # DELETE /bye -> undef
364 $r->route('/bye')->via(qw/get post/)
365 ->to(controller => 'foo', action => 'bye');
366
367 Nested Routes
368 It is also possible to build tree structures from routes to remove
369 repetitive code, an endpoint is required to actually match though.
370
371 # /foo -> undef
372 # /foo/bar -> {controller => 'foo', action => 'bar'}
373 my $foo = $r->route('/foo')->to(controller => 'foo');
374 $foo->route('/bar')->to(action => 'bar');
375
376 The stash will simply move from route to route and newer values
377 override old ones.
378
379 # /foo -> undef
380 # /foo/abc -> undef
381 # /foo/bar -> {controller => 'foo', action => 'bar'}
382 # /foo/baz -> {controller => 'foo', action => 'baz'}
383 # /foo/cde -> {controller => 'foo', action => 'abc'}
384 my $foo = $r->route('/foo')->to(controller => 'foo', action => 'abc');
385 $foo->route('/bar')->to(action => 'bar');
386 $foo->route('/baz')->to(action => 'baz');
387 $foo->route('/cde');
388
390 Less commonly used and more powerful features.
391
392 Waypoints
393 Waypoints are very similar to normal nested routes but can match even
394 if they are not an endpoint themself.
395
396 # /foo -> {controller => 'foo', action => 'baz'}
397 # /foo/bar -> {controller => 'foo', action => 'bar'}
398 my $foo = $r->waypoint('/foo')->to(controller => 'foo', action => 'baz');
399 $foo->route('/bar')->to(action => 'bar');
400
401 Bridges
402 Bridges unlike nested routes and waypoints always match and result in
403 additional dispatch cycles.
404
405 # /foo -> undef
406 # /foo/bar -> {controller => 'foo', action => 'baz'}
407 # {controller => 'foo', action => 'bar'}
408 my $foo = $r->bridge('/foo')->to(controller => 'foo', action => 'baz');
409 $foo->route('/bar')->to(action => 'bar');
410
411 The actual bridge code needs to return a true value or the dispatch
412 chain will be broken, this makes bridges a very powerful tool for
413 authentication.
414
415 # /foo -> undef
416 # /foo/bar -> {cb => sub {...}}
417 # {controller => 'foo', action => 'bar'}
418 my $foo = $r->bridge('/foo')->to(cb => sub {
419 my $self = shift;
420
421 # Authenticated
422 return 1 if $self->req->headers->header('X-Bender');
423
424 # Not authenticated
425 return;
426 });
427 $foo->route('/bar')->to(controller => 'foo', action => 'bar');
428
429 More Restrictive Placeholders
430 You can adjust the regular expressions behind placeholders to better
431 suit your needs, just make sure not to use "^", "$" and "()", because
432 placeholders become part of a larger regular expression internally.
433
434 # /23 -> {controller => 'foo', action => 'bar', number => 23}
435 # /test -> undef
436 $r->route('/:number', number => qr/\d+/)
437 ->to(controller => 'foo', action => 'bar');
438
439 # /23 -> undef
440 # /test -> {controller => 'foo', action => 'bar', name => 'test'}
441 $r->route('/:name', name => qr/\[a-zA-Z]+/)
442 ->to(controller => 'foo', action => 'bar');
443
444 This way you get easily readable routes and the raw power of regular
445 expressions.
446
447 Conditions
448 Sometimes you might need a little more power, for example to check the
449 "User-Agent" header in multiple routes. This is where conditions come
450 into play, they are basically router plugins.
451
452 # Simple "User-Agent" condition
453 $r->add_condition(
454 agent => sub {
455 my ($r, $c, $captures, $pattern) = @_;
456
457 # User supplied regular expression
458 return unless $pattern && ref $pattern eq 'Regexp';
459
460 # Match "User-Agent" header and return captured values on success
461 my $agent = $c->req->headers->user_agent;
462 return $captures if $agent && $agent =~ $pattern;
463
464 # No success
465 return;
466 }
467 );
468
469 # /firefox_only (Firefox) -> {controller => 'foo', action => 'bar'}
470 $r->route('/firefox_only')->over(agent => qr/Firefox/)
471 ->to(controller => 'foo', action => 'bar');
472
473 The method "add_condition" registers the new condition in the router
474 while "over" actually applies it to the route.
475
476 Condition Plugins
477 You can also package your conditions as reusable plugins.
478
479 # Plugin
480 package Mojolicious::Plugin::WerewolfCondition;
481 use base 'Mojolicious::Plugin';
482
483 use Astro::MoonPhase;
484
485 sub register {
486 my ($self, $app) = @_;
487
488 # Add "werewolf" condition
489 $app->routes->add_condition(
490 werewolf => sub {
491 my ($r, $c, $captures, $days) = @_;
492
493 # Keep the werewolfs out!
494 return if abs(14 - (phase(time))[2]) > ($days / 2);
495
496 # It's ok, no werewolf
497 return $captures;
498 }
499 );
500 }
501
502 1;
503
504 Now just load the plugin and you are ready to use the condition in all
505 your applications.
506
507 # Application
508 package MyApp;
509 use base 'Mojolicious';
510
511 sub startup {
512 my $self = shift;
513
514 # Plugin
515 $self->plugin('werewolf_condition');
516
517 # Routes
518 my $r = $self->routes;
519
520 # /hideout (keep them out for 4 days after full moon)
521 $r->route('/hideout')->over(werewolf => 4)
522 ->to(controller => 'foo', action => 'bar');
523 }
524
525 1;
526
527 Embedding Applications
528 You can easily embed whole applications simply by using them instead of
529 a controller. This allows for example the use of the Mojolicious::Lite
530 domain specific language in normal Mojolicious controllers.
531
532 # Controller
533 package MyApp::Bar;
534 use Mojolicious::Lite;
535
536 # GET /hello
537 get '/hello' => sub {
538 my $self = shift;
539 my $name = $self->param('name');
540 $self->render(text => "Hello $name!");
541 };
542
543 1;
544
545 With the "detour" method which is very similar to "to", you can allow
546 the route to partially match and use only the remaining path in the
547 embedded application.
548
549 # /foo/*
550 $r->route('/foo')->detour('bar#', name => 'Mojo');
551
552 A minimal embeddable application is nothing more than a subclass of
553 Mojo, containing a "handler" method accepting Mojolicious::Controller
554 objects.
555
556 package MyApp::Bar;
557 use base 'Mojo';
558
559 sub handler {
560 my ($self, $c) = @_;
561 $c->res->code(200);
562 my $name = $c->param('name');
563 $c->res->body("Hello $name!");
564 }
565
566 1;
567
568 Because the remaining path always gets stored in the "path" stash
569 value, you could also just use it directly instead of "detour".
570
571 # /foo/*
572 $r->route('/foo/(*path)')->to('bar#', name => 'Mojo');
573
574 Application Plugins
575 Embedding Mojolicious applications is easy, but it gets even easier if
576 you package the whole thing as a self contained reusable plugin.
577
578 # Plugin
579 package Mojolicious::Plugin::MyEmbeddedApp;
580 use base 'Mojolicious::Plugin';
581
582 sub register {
583 my ($self, $app) = @_;
584
585 # Automatically add route
586 $app->routes->route('/foo')->detour(app => EmbeddedApp::app());
587 }
588
589 package EmbeddedApp;
590 use Mojolicious::Lite;
591
592 get '/bar' => 'bar';
593
594 1;
595 __DATA__
596 @@ bar.html.ep
597 Hello World!
598
599 The "app" stash value can be used for already instantiated
600 applications. Now just load the plugin and you're done.
601
602 # Application
603 package MyApp;
604 use base 'Mojolicious';
605
606 sub startup {
607 my $self = shift;
608
609 # Plugin
610 $self->plugin('my_embedded_app');
611 }
612
613 1;
614
615 WebSockets
616 You can restrict access to WebSocket handshakes using the "websocket"
617 method.
618
619 # /ws (WebSocket handshake)
620 $r->route('/echo')->websocket->to(controller => 'foo', action => 'echo');
621
622 # Controller
623 package MyApp::Foo;
624 use base 'Mojolicious::Controller';
625
626 # Action
627 sub echo {
628 my $self = shift;
629 $self->receive_message(
630 sub {
631 my ($self, $message) = @_;
632 $self->send_message("echo: $message");
633 }
634 );
635 }
636
637 1;
638
639 IRIs
640 IRIs are handled transparently, that means paths are guaranteed to be
641 unescaped and decoded to Perl characters.
642
643 use utf8;
644
645 # /X (unicode snowman) -> {controller => 'foo', action => 'snowman'}
646 $r->route('/X')->to(controller => 'foo', action => 'snowman');
647
648 Just don't forget to use the utf8 pragma or you'll make the unicode
649 snowman very sad.
650
651 Introspection
652 The "routes" command can be used from the command line to list all
653 available routes together with underlying regular expressions.
654
655 % script/myapp routes
656 /foo/:name (?-xism:^/foo/([^\/\.]+))
657 /bar/(.test) (?-xism:^/bar/([^\/]+))
658 /baz/(*everything) (?-xism:^/baz/(.+))
659
660
661
662perl v5.12.3 2010-08-14 Mojolicious::Guides::Routing(3)