1Mojolicious::Guides::RoUusteirngC(o3n)tributed Perl DocuMmoejnotlaitciioonus::Guides::Routing(3)
2
3
4

NAME

6       Mojolicious::Guides::Routing - Routing
7

OVERVIEW

9       This document contains a simple and fun introduction to the Mojolicious
10       router and its underlying concepts.
11

CONCEPTS

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

BASICS

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

ADVANCED

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)
Impressum