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

NAME

6       Mojolicious::Guides::Routing - Routing requests
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 -> $c->render(text => 'Daniel');
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 path part
24       of the request URL to some kind of response generator.
25
26         /user/show/2 -> $c->render(text => 'Isabell');
27         /user/show/3 -> $c->render(text => 'Sara');
28         /user/show/4 -> $c->render(text => 'Stefan');
29         /user/show/5 -> $c->render(text => 'Fynn');
30
31       While it is very well possible to make all these connections static, it
32       is also rather inefficient. That's why regular expressions are commonly
33       used to make the dispatch process more dynamic.
34
35         qr!/user/show/(\d+)! -> $c->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: 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+)! -> $c->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 -> $c->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       A trailing slash in the path is always optional.
78
79         /user/show/23/ -> /user/:action/:id -> {action => 'show', id => 23}
80
81   Reversibility
82       One more huge advantage routes have over regular expressions is that
83       they are easily reversible, extracted placeholders can be turned back
84       into a path at any time.
85
86         /sebastian -> /:name -> {name => 'sebastian'}
87         {name => 'sebastian'} -> /:name -> /sebastian
88
89       Every placeholder has a name, even if it's just an empty string.
90
91   Standard placeholders
92       Standard placeholders are the simplest form of placeholders, they use a
93       colon prefix and match all characters except "/" and ".", similar to
94       the regular expression "([^/.]+)".
95
96         /hello              -> /:name/hello -> undef
97         /sebastian/23/hello -> /:name/hello -> undef
98         /sebastian.23/hello -> /:name/hello -> undef
99         /sebastian/hello    -> /:name/hello -> {name => 'sebastian'}
100         /sebastian23/hello  -> /:name/hello -> {name => 'sebastian23'}
101         /sebastian 23/hello -> /:name/hello -> {name => 'sebastian 23'}
102
103       All placeholders can be surrounded by "<" and ">" to separate them from
104       the surrounding text.
105
106         /hello             -> /<:name>hello -> undef
107         /sebastian/23hello -> /<:name>hello -> undef
108         /sebastian.23hello -> /<:name>hello -> undef
109         /sebastianhello    -> /<:name>hello -> {name => 'sebastian'}
110         /sebastian23hello  -> /<:name>hello -> {name => 'sebastian23'}
111         /sebastian 23hello -> /<:name>hello -> {name => 'sebastian 23'}
112
113       The colon prefix is optional for standard placeholders that are
114       surrounded by "<" and ">".
115
116         /i♥mojolicious -> /<one>♥<two> -> {one => 'i', two => 'mojolicious'}
117
118   Relaxed placeholders
119       Relaxed placeholders are just like standard placeholders, but use a
120       hash prefix and match all characters except "/", similar to the regular
121       expression "([^/]+)".
122
123         /hello              -> /#name/hello -> undef
124         /sebastian/23/hello -> /#name/hello -> undef
125         /sebastian.23/hello -> /#name/hello -> {name => 'sebastian.23'}
126         /sebastian/hello    -> /#name/hello -> {name => 'sebastian'}
127         /sebastian23/hello  -> /#name/hello -> {name => 'sebastian23'}
128         /sebastian 23/hello -> /#name/hello -> {name => 'sebastian 23'}
129
130       They can be especially useful for manually matching file names with
131       extensions, rather than using format detection.
132
133         /music/song.mp3 -> /music/#filename -> {filename => 'song.mp3'}
134
135   Wildcard placeholders
136       Wildcard placeholders are just like the two types of placeholders
137       above, but use an asterisk prefix and match absolutely everything,
138       including "/" and ".", similar to the regular expression "(.+)".
139
140         /hello              -> /*name/hello -> undef
141         /sebastian/23/hello -> /*name/hello -> {name => 'sebastian/23'}
142         /sebastian.23/hello -> /*name/hello -> {name => 'sebastian.23'}
143         /sebastian/hello    -> /*name/hello -> {name => 'sebastian'}
144         /sebastian23/hello  -> /*name/hello -> {name => 'sebastian23'}
145         /sebastian 23/hello -> /*name/hello -> {name => 'sebastian 23'}
146
147       They can be useful for manually matching entire file paths.
148
149         /music/rock/song.mp3 -> /music/*filepath -> {filepath => 'rock/song.mp3'}
150

BASICS

152       Most commonly used features every Mojolicious developer should know
153       about.
154
155   Minimal route
156       The attribute "routes" in Mojolicious contains a router you can use to
157       generate route structures.
158
159         # Application
160         package MyApp;
161         use Mojo::Base 'Mojolicious';
162
163         sub startup {
164           my $self = shift;
165
166           # Router
167           my $r = $self->routes;
168
169           # Route
170           $r->get('/welcome')->to(controller => 'foo', action => 'welcome');
171         }
172
173         1;
174
175       The minimal route above will load and instantiate the class
176       "MyApp::Controller::Foo" and call its "welcome" method. Routes are
177       usually configured in the "startup" method of the application class,
178       but the router can be accessed from everywhere (even at runtime).
179
180         # Controller
181         package MyApp::Controller::Foo;
182         use Mojo::Base 'Mojolicious::Controller';
183
184         # Action
185         sub welcome {
186           my $self = shift;
187
188           # Render response
189           $self->render(text => 'Hello there.');
190         }
191
192         1;
193
194       All routes match in the same order in which they were defined, and
195       matching stops as soon as a suitable route has been found. So you can
196       improve the routing performance by declaring your most frequently
197       accessed routes first. A routing cache will also be used automatically
198       to handle sudden traffic spikes more gracefully.
199
200   Routing destination
201       After you start a new route with methods like "get" in
202       Mojolicious::Routes::Route, you can also give it a destination in the
203       form of a hash using the chained method "to" in
204       Mojolicious::Routes::Route.
205
206         # /welcome -> {controller => 'foo', action => 'welcome'}
207         $r->get('/welcome')->to(controller => 'foo', action => 'welcome');
208
209       Now if the route matches an incoming request it will use the content of
210       this hash to try and find appropriate code to generate a response.
211
212   HTTP methods
213       There are already shortcuts for the most common HTTP request methods
214       like "post" in Mojolicious::Routes::Route, and for more control "any"
215       in Mojolicious::Routes::Route accepts an optional array reference with
216       arbitrary request methods as first argument.
217
218         # PUT /hello  -> undef
219         # GET /hello  -> {controller => 'foo', action => 'hello'}
220         $r->get('/hello')->to(controller => 'foo', action => 'hello');
221
222         # PUT /hello -> {controller => 'foo', action => 'hello'}
223         $r->put('/hello')->to(controller => 'foo', action => 'hello');
224
225         # POST /hello -> {controller => 'foo', action => 'hello'}
226         $r->post('/hello')->to(controller => 'foo', action => 'hello');
227
228         # GET|POST /bye  -> {controller => 'foo', action => 'bye'}
229         $r->any(['GET', 'POST'] => '/bye')->to(controller => 'foo', action => 'bye');
230
231         # * /whatever -> {controller => 'foo', action => 'whatever'}
232         $r->any('/whatever')->to(controller => 'foo', action => 'whatever');
233
234       There is one small exception, "HEAD" requests are considered equal to
235       "GET", but content will not be sent with the response even if it is
236       present.
237
238         # GET /test  -> {controller => 'bar', action => 'test'}
239         # HEAD /test -> {controller => 'bar', action => 'test'}
240         $r->get('/test')->to(controller => 'bar', action => 'test');
241
242       You can also use the "_method" query parameter to override the request
243       method.  This can be very useful when submitting forms with browsers
244       that only support "GET" and "POST".
245
246         # PUT  /stuff             -> {controller => 'baz', action => 'stuff'}
247         # POST /stuff?_method=PUT -> {controller => 'baz', action => 'stuff'}
248         $r->put('/stuff')->to(controller => 'baz', action => 'stuff');
249
250   IRIs
251       IRIs are handled transparently, that means paths are guaranteed to be
252       unescaped and decoded from bytes to characters.
253
254         # GET /☃ (Unicode snowman) -> {controller => 'foo', action => 'snowman'}
255         $r->get('/☃')->to(controller => 'foo', action => 'snowman');
256
257   Stash
258       The generated hash of a matching route is actually the center of the
259       whole Mojolicious request cycle. We call it the stash, and it persists
260       until a response has been generated.
261
262         # /bye -> {controller => 'foo', action => 'bye', mymessage => 'Bye'}
263         $r->get('/bye')
264           ->to(controller => 'foo', action => 'bye', mymessage => 'Bye');
265
266       There are a few stash values with special meaning, such as "controller"
267       and "action", but you can generally fill it with whatever data you need
268       to generate a response. Once dispatched the whole stash content can be
269       changed at any time.
270
271         sub bye {
272           my $self = shift;
273
274           # Get message from stash
275           my $msg = $self->stash('mymessage');
276
277           # Change message in stash
278           $self->stash(mymessage => 'Welcome');
279         }
280
281       For a full list of reserved stash values see "stash" in
282       Mojolicious::Controller.
283
284   Nested routes
285       It is also possible to build tree structures from routes to remove
286       repetitive code. A route with children can't match on its own though,
287       only the actual endpoints of these nested routes can.
288
289         # /foo     -> undef
290         # /foo/bar -> {controller => 'foo', action => 'bar'}
291         my $foo = $r->any('/foo')->to(controller => 'foo');
292         $foo->get('/bar')->to(action => 'bar');
293
294       The stash is simply inherited from route to route and newer values
295       override old ones.
296
297         # /cats      -> {controller => 'cats', action => 'index'}
298         # /cats/nyan -> {controller => 'cats', action => 'nyan'}
299         # /cats/lol  -> {controller => 'cats', action => 'default'}
300         my $cats = $r->any('/cats')->to(controller => 'cats', action => 'default');
301         $cats->get('/')->to(action => 'index');
302         $cats->get('/nyan')->to(action => 'nyan');
303         $cats->get('/lol');
304
305       With a few common prefixes you can also greatly improve the routing
306       performance of applications with many routes, because children are only
307       tried if the prefix matched first.
308
309   Special stash values
310       When the dispatcher sees "controller" and "action" values in the stash
311       it will always try to turn them into a class and method to dispatch to.
312       The "controller" value gets converted from "snake_case" to "CamelCase"
313       using "camelize" in Mojo::Util and appended to one or more namespaces,
314       defaulting to a controller namespace based on the application class
315       ("MyApp::Controller"), as well as the bare application class ("MyApp"),
316       and these namespaces are searched in that order. The action value is
317       not changed at all, so both values are case-sensitive.
318
319         # Application
320         package MyApp;
321         use Mojo::Base 'Mojolicious';
322
323         sub startup {
324           my $self = shift;
325
326           # /bye -> MyApp::Controller::Foo->bye
327           $self->routes->get('/bye')->to(controller => 'foo', action => 'bye');
328         }
329
330         1;
331
332         # Controller
333         package MyApp::Controller::Foo;
334         use Mojo::Base 'Mojolicious::Controller';
335
336         # Action
337         sub bye {
338           my $self = shift;
339
340           # Render response
341           $self->render(text => 'Good bye.');
342         }
343
344         1;
345
346       Controller classes are perfect for organizing code in larger projects.
347       There are more dispatch strategies, but because controllers are the
348       most commonly used ones they also got a special shortcut in the form of
349       "controller#action".
350
351         # /bye -> {controller => 'foo', action => 'bye', mymessage => 'Bye'}
352         $r->get('/bye')->to('foo#bye', mymessage => 'Bye');
353
354       During camelization "-" characters get replaced with "::", this allows
355       multi-level "controller" hierarchies.
356
357         # / -> MyApp::Controller::Foo::Bar->hi
358         $r->get('/')->to('foo-bar#hi');
359
360       You can also just specify the "controller" in CamelCase form instead of
361       snake_case.
362
363         # / -> MyApp::Controller::Foo::Bar->hi
364         $r->get('/')->to('Foo::Bar#hi');
365
366       For security reasons the dispatcher will always check if the
367       "controller" is actually a subclass of Mojolicious::Controller or Mojo
368       before dispatching to it.
369
370   Namespaces
371       You can use the "namespace" stash value to change the namespace of a
372       whole route with all its children.
373
374         # /bye -> MyApp::MyController::Foo::Bar->bye
375         $r->get('/bye')
376           ->to(namespace => 'MyApp::MyController::Foo::Bar', action => 'bye');
377
378       The "controller" is always converted from "snake_case" to "CamelCase"
379       with "camelize" in Mojo::Util, and then appended to this "namespace".
380
381         # /bye -> MyApp::MyController::Foo::Bar->bye
382         $r->get('/bye')->to('foo-bar#bye', namespace => 'MyApp::MyController');
383
384         # /hey -> MyApp::MyController::Foo::Bar->hey
385         $r->get('/hey')->to('Foo::Bar#hey', namespace => 'MyApp::MyController');
386
387       You can also change the default namespaces for all routes in the
388       application with the router attribute "namespaces" in
389       Mojolicious::Routes, which usually defaults to a namespace based on the
390       application class ("MyApp::Controller"), as well as the bare
391       application class ("MyApp").
392
393         $r->namespaces(['MyApp::MyController']);
394
395   Route to callback
396       The "cb" stash value, which won't be inherited by nested routes, can be
397       used to bypass controllers and execute a callback instead.
398
399         $r->get('/bye')->to(cb => sub {
400           my $c = shift;
401           $c->render(text => 'Good bye.');
402         });
403
404       But just like in Mojolicious::Lite you can also pass the callback
405       directly, which usually looks much better.
406
407         $r->get('/bye' => sub {
408           my $c = shift;
409           $c->render(text => 'Good bye.');
410         });
411
412   Named routes
413       Naming your routes will allow backreferencing in many methods and
414       helpers throughout the whole framework, most of which internally rely
415       on "url_for" in Mojolicious::Controller for this.
416
417         # /foo/marcus -> {controller => 'foo', action => 'bar', user => 'marcus'}
418         $r->get('/foo/:user')->to('foo#bar')->name('baz');
419
420         # Generate URL "/foo/marcus" for route "baz"
421         my $url = $c->url_for('baz');
422
423         # Generate URL "/foo/jan" for route "baz"
424         my $url = $c->url_for('baz', user => 'jan');
425
426         # Generate URL "http://127.0.0.1:3000/foo/jan" for route "baz"
427         my $url = $c->url_for('baz', user => 'jan')->to_abs;
428
429       You can assign a name with "name" in Mojolicious::Routes::Route, or let
430       the router generate one automatically, which would be equal to the
431       route itself without non-word characters, custom names have a higher
432       precedence though.
433
434         # /foo/bar ("foobar")
435         $r->get('/foo/bar')->to('test#stuff');
436
437         # Generate URL "/foo/bar"
438         my $url = $c->url_for('foobar');
439
440       To refer to the current route you can use the reserved name "current"
441       or no name at all.
442
443         # Generate URL for current route
444         my $url = $c->url_for('current');
445         my $url = $c->url_for;
446
447       To check or get the name of the current route you can use the helper
448       "current_route" in Mojolicious::Plugin::DefaultHelpers.
449
450         # Name for current route
451         my $name = $c->current_route;
452
453         # Check route name in code shared by multiple routes
454         $c->stash(button => 'green') if $c->current_route('login');
455
456   Optional placeholders
457       Extracted placeholder values will simply redefine older stash values if
458       they already exist.
459
460         # /bye -> {controller => 'foo', action => 'bar', mymessage => 'bye'}
461         # /hey -> {controller => 'foo', action => 'bar', mymessage => 'hey'}
462         $r->get('/:mymessage')->to('foo#bar', mymessage => 'hi');
463
464       One more interesting effect, a placeholder automatically becomes
465       optional if there is already a stash value of the same name present,
466       this works similar to the regular expression "([^/.]+)?".
467
468         # / -> {controller => 'foo', action => 'bar', mymessage => 'hi'}
469         $r->get('/:mymessage')->to('foo#bar', mymessage => 'hi');
470
471         # /test/123     -> {controller => 'foo', action => 'bar', mymessage => 'hi'}
472         # /test/bye/123 -> {controller => 'foo', action => 'bar', mymessage => 'bye'}
473         $r->get('/test/:mymessage/123')->to('foo#bar', mymessage => 'hi');
474
475       And if two optional placeholders are only separated by a slash, that
476       slash can become optional as well.
477
478         # /           -> {controller => 'foo',   action => 'bar'}
479         # /users      -> {controller => 'users', action => 'bar'}
480         # /users/list -> {controller => 'users', action => 'list'}
481         $r->get('/:controller/:action')->to('foo#bar');
482
483       Special stash values like "controller" and "action" can also be
484       placeholders, which is very convenient especially during development,
485       but should only be used very carefully, because every controller method
486       becomes a potential route. All uppercase methods as well as those
487       starting with an underscore are automatically hidden from the router
488       and you can use "hide" in Mojolicious::Routes to add additional ones.
489
490         # Hide "create" method in all controllers
491         $r->hide('create');
492
493       This has already been done for all attributes and methods from
494       Mojolicious::Controller.
495
496   Restrictive placeholders
497       A very easy way to make placeholders more restrictive are alternatives,
498       you just make a list of possible values, which then work similar to the
499       regular expression "(bender|leela)".
500
501         # /fry    -> undef
502         # /bender -> {controller => 'foo', action => 'bar', name => 'bender'}
503         # /leela  -> {controller => 'foo', action => 'bar', name => 'leela'}
504         $r->get('/:name' => [name => ['bender', 'leela']])->to('foo#bar');
505
506       You can also adjust the regular expressions behind placeholders
507       directly, just make sure not to use "^" and "$" or capturing groups
508       "(...)", because placeholders become part of a larger regular
509       expression internally, non-capturing groups "(?:...)" are fine though.
510
511         # /23   -> {controller => 'foo', action => 'bar', number => 23}
512         # /test -> undef
513         $r->get('/:number' => [number => qr/\d+/])->to('foo#bar');
514
515         # /23   -> undef
516         # /test -> {controller => 'foo', action => 'bar', name => 'test'}
517         $r->get('/:name' => [name => qr/[a-zA-Z]+/])->to('foo#bar');
518
519       This way you get easily readable routes and the raw power of regular
520       expressions.
521
522   Placeholder types
523       And if you have multiple routes using restrictive placeholders you can
524       also turn them into placeholder types with "add_type" in
525       Mojolicious::Routes.
526
527         # A type with alternatives
528         $r->add_type(futurama_name => ['bender', 'leela']);
529
530         # /fry    -> undef
531         # /bender -> {controller => 'foo', action => 'bar', name => 'bender'}
532         # /leela  -> {controller => 'foo', action => 'bar', name => 'leela'}
533         $r->get('/<name:futurama_name>')->to('foo#bar');
534
535       Placeholder types work just like restrictive placeholders, they are
536       just reusable with the "<placeholder:type>" notation.
537
538         # A type adjusting the regular expression
539         $r->add_type(upper => qr/[A-Z]+/);
540
541         # /user/ROOT -> {controller => 'users', action => 'show', name => 'ROOT'}
542         # /user/root -> undef
543         # /user/23   -> undef
544         $r->get('/user/<name:upper>')->to('users#show');
545
546       Some types like "num" are used so commonly that they are available by
547       default.
548
549         # /article/12   -> {controller => 'article', action => 'show', id => 12}
550         # /article/test -> undef
551         $r->get('/article/<id:num>')->to('articles#show');
552
553       For a full list of available placeholder types see also "TYPES" in
554       Mojolicious::Routes.
555
556   Introspection
557       The command Mojolicious::Command::routes can be used from the command
558       line to list all available routes together with names and underlying
559       regular expressions.
560
561         $ ./myapp.pl routes -v
562         /foo/:name  ....  POST  fooname  ^/foo/([^/.]+)/?(?:\.([^/]+))?$
563         /bar        ..U.  *     bar      ^/bar
564           +/baz     ...W  GET   baz      ^/baz/?(?:\.([^/]+))?$
565         /yada       ....  *     yada     ^/yada/?(?:\.([^/]+))?$
566
567   Under
568       To share code with multiple nested routes you can use "under" in
569       Mojolicious::Routes::Route, because unlike normal nested routes, the
570       routes generated with it have their own intermediate destination and
571       result in additional dispatch cycles when they match.
572
573         # /foo     -> undef
574         # /foo/bar -> {controller => 'foo', action => 'baz'}
575         #             {controller => 'foo', action => 'bar'}
576         my $foo = $r->under('/foo')->to('foo#baz');
577         $foo->get('/bar')->to('#bar');
578
579       The actual action code for this destination needs to return a true
580       value or the dispatch chain will be broken, this can be a very powerful
581       tool for authentication.
582
583         # /blackjack -> {cb => sub {...}}
584         #               {controller => 'hideout', action => 'blackjack'}
585         my $auth = $r->under('/' => sub {
586           my $c = shift;
587
588           # Authenticated
589           return 1 if $c->req->headers->header('X-Bender');
590
591           # Not authenticated
592           $c->render(text => "You're not Bender.", status => 401);
593           return undef;
594         });
595         $auth->get('/blackjack')->to('hideout#blackjack');
596
597       Broken dispatch chains can be continued by calling "continue" in
598       Mojolicious::Plugin::DefaultHelpers, this allows for example, non-
599       blocking operations to finish before reaching the next dispatch cycle.
600
601         my $maybe = $r->under('/maybe' => sub {
602           my $c = shift;
603
604           # Wait 3 seconds and then give visitors a 50% chance to continue
605           Mojo::IOLoop->timer(3 => sub {
606
607             # Loser
608             return $c->render(text => 'No luck.') unless int rand 2;
609
610             # Winner
611             $c->continue;
612           });
613
614           return undef;
615         });
616         $maybe->get('/')->to('maybe#winner');
617
618       Every destination is just a snapshot of the stash at the time the route
619       matched, and only the "format" value is shared by all of them. For a
620       little more power you can introspect the preceding and succeeding
621       destinations with "match" in Mojolicious::Controller.
622
623         # Action of the fourth dispatch cycle
624         my $action = $c->match->stack->[3]{action};
625
626   Formats
627       File extensions like ".html" and ".txt" at the end of a route are
628       automatically detected and stored in the stash value "format".
629
630         # /foo      -> {controller => 'foo', action => 'bar'}
631         # /foo.html -> {controller => 'foo', action => 'bar', format => 'html'}
632         # /foo.txt  -> {controller => 'foo', action => 'bar', format => 'txt'}
633         $r->get('/foo')->to('foo#bar');
634
635       This for example, allows multiple templates in different formats to
636       share the same action code. Restrictive placeholders can also be used
637       to limit the allowed formats.
638
639         # /foo.txt -> undef
640         # /foo.rss -> {controller => 'foo', action => 'bar', format => 'rss'}
641         # /foo.xml -> {controller => 'foo', action => 'bar', format => 'xml'}
642         $r->get('/foo' => [format => ['rss', 'xml']])->to('foo#bar');
643
644       A "format" value can also be passed to "url_for" in
645       Mojolicious::Controller.
646
647         # /foo/bar.txt -> {controller => 'foo', action => 'bar', format => 'txt'}
648         $r->get('/foo/:action')->to('foo#')->name('baz');
649
650         # Generate URL "/foo/bar.txt" for route "baz"
651         my $url = $c->url_for('baz', action => 'bar', format => 'txt');
652
653       Or you can just disable format detection with a special type of
654       restrictive placeholder, which gets inherited by nested routes, and
655       then re-enable it on demand.
656
657         # /foo      -> {controller => 'foo', action => 'bar'}
658         # /foo.html -> undef
659         $r->get('/foo' => [format => 0])->to('foo#bar');
660
661         # /foo      -> {controller => 'foo', action => 'bar'}
662         # /foo.html -> undef
663         # /baz      -> undef
664         # /baz.txt  -> {controller => 'baz', action => 'yada', format => 'txt'}
665         # /baz.html -> {controller => 'baz', action => 'yada', format => 'html'}
666         # /baz.xml  -> undef
667         my $inactive = $r->under([format => 0]);
668         $inactive->get('/foo')->to('foo#bar');
669         $inactive->get('/baz' => [format => ['txt', 'html']])->to('baz#yada');
670
671   WebSockets
672       With the method "websocket" in Mojolicious::Routes::Route you can
673       restrict access to WebSocket handshakes, which are normal "GET"
674       requests with some additional information.
675
676         # /echo (WebSocket handshake)
677         $r->websocket('/echo')->to('foo#echo');
678
679         # Controller
680         package MyApp::Controller::Foo;
681         use Mojo::Base 'Mojolicious::Controller';
682
683         # Action
684         sub echo {
685           my $self = shift;
686           $self->on(message => sub {
687             my ($self, $msg) = @_;
688             $self->send("echo: $msg");
689           });
690         }
691
692         1;
693
694       The connection gets established when you respond to the WebSocket
695       handshake request with a 101 response status, which happens
696       automatically if you subscribe to an event with "on" in
697       Mojolicious::Controller or send a message with "send" in
698       Mojolicious::Controller right away.
699
700         GET /echo HTTP/1.1
701         Host: mojolicious.org
702         User-Agent: Mojolicious (Perl)
703         Connection: Upgrade
704         Upgrade: websocket
705         Sec-WebSocket-Key: IDM3ODE4NDk2MjA1OTcxOQ==
706         Sec-WebSocket-Version: 13
707
708         HTTP/1.1 101 Switching Protocols
709         Server: Mojolicious (Perl)
710         Date: Tue, 03 Feb 2015 17:08:24 GMT
711         Connection: Upgrade
712         Upgrade: websocket
713         Sec-WebSocket-Accept: SWsp5N2iNxPbHlcOTIw8ERvyVPY=
714
715   Catch-all route
716       Since routes match in the order in which they were defined, you can
717       catch all requests that did not match in your last route with an
718       optional wildcard placeholder.
719
720         # * /*
721         $r->any('/*whatever' => {whatever => ''} => sub {
722           my $c        = shift;
723           my $whatever = $c->param('whatever');
724           $c->render(text => "/$whatever did not match.", status => 404);
725         });
726
727   Conditions
728       Conditions such as "headers", "agent" and "host" from
729       Mojolicious::Plugin::HeaderCondition can be applied to any route with
730       the method "over" in Mojolicious::Routes::Route, and allow even more
731       powerful route constructs.
732
733         # / (Origin: http://perl.org)
734         $r->get('/')->over(headers => {Origin => qr/perl\.org/})->to('foo#bar');
735
736         # / (Firefox)
737         $r->get('/')->over(agent => qr/Firefox/)->to('browser-test#firefox');
738
739         # / (Internet Explorer)
740         $r->get('/')->over(agent => qr/Internet Explorer/)->to('browser-test#ie');
741
742         # http://mojolicious.org/perldoc
743         $r->get('/perldoc')->over(host => 'mojolicious.org')->to('perldoc#index');
744
745       Just be aware that conditions are too complex for the routing cache,
746       which normally speeds up recurring requests, and can therefore reduce
747       performance.
748
749   Hooks
750       Hooks operate outside the routing system and allow you to extend the
751       framework itself by sharing code with all requests indiscriminately
752       through "hook" in Mojolicious, which makes them a very powerful tool
753       especially for plugins.
754
755         # Application
756         package MyApp;
757         use Mojo::Base 'Mojolicious';
758
759         sub startup {
760           my $self = shift;
761
762           # Check all requests for a "/test" prefix
763           $self->hook(before_dispatch => sub {
764             my $c = shift;
765             $c->render(text => 'This request did not reach the router.')
766               if $c->req->url->path->contains('/test');
767           });
768
769           # These will not be reached if the hook above renders a response
770           my $r = $self->routes;
771           $r->get('/welcome')->to('foo#welcome');
772           $r->post('/bye')->to('foo#bye');
773         }
774
775         1;
776
777       Post-processing the response to add or remove headers is a very common
778       use.
779
780         # Make sure static files are cached
781         $app->hook(after_static => sub {
782           my $c = shift;
783           $c->res->headers->cache_control('max-age=3600, must-revalidate');
784         });
785
786         # Remove a default header
787         $app->hook(after_dispatch => sub {
788           my $c = shift;
789           $c->res->headers->remove('Server');
790         });
791
792       Same for pre-processing the request.
793
794         # Choose template variant based on request headers
795         $app->hook(before_dispatch => sub {
796           my $c = shift;
797           return unless my $agent = $c->req->headers->user_agent;
798           $c->stash(variant => 'ie') if $agent =~ /Internet Explorer/;
799         });
800
801       Or more advanced extensions to add monitoring to your application.
802
803         # Forward exceptions to a web service
804         $app->hook(after_dispatch => sub {
805           my $c = shift;
806           return unless my $e = $c->stash('exception');
807           $c->ua->post('https://example.com/bugs' => form => {exception => $e});
808         });
809
810       You can even extend much of the core functionality.
811
812         # Make controller object available to actions as $_
813         $app->hook(around_action => sub {
814           my ($next, $c, $action, $last) = @_;
815           local $_ = $c;
816           return $next->();
817         });
818
819         # Pass route name as argument to actions
820         $app->hook(around_action => sub {
821           my ($next, $c, $action, $last) = @_;
822           return $c->$action($c->current_route);
823         });
824
825       For a full list of available hooks see "HOOKS" in Mojolicious.
826

ADVANCED

828       Less commonly used and more powerful features.
829
830   Shortcuts
831       To make route generation more expressive, you can also add your own
832       shortcuts with "add_shortcut" in Mojolicious::Routes.
833
834         # Simple "resource" shortcut
835         $r->add_shortcut(resource => sub {
836           my ($r, $name) = @_;
837
838           # Prefix for resource
839           my $resource = $r->any("/$name")->to("$name#");
840
841           # Render a list of resources
842           $resource->get('/')->to('#index')->name($name);
843
844           # Render a form to create a new resource (submitted to "store")
845           $resource->get('/create')->to('#create')->name("create_$name");
846
847           # Store newly created resource (submitted by "create")
848           $resource->post->to('#store')->name("store_$name");
849
850           # Render a specific resource
851           $resource->get('/:id')->to('#show')->name("show_$name");
852
853           # Render a form to edit a resource (submitted to "update")
854           $resource->get('/:id/edit')->to('#edit')->name("edit_$name");
855
856           # Store updated resource (submitted by "edit")
857           $resource->put('/:id')->to('#update')->name("update_$name");
858
859           # Remove a resource
860           $resource->delete('/:id')->to('#remove')->name("remove_$name");
861
862           return $resource;
863         });
864
865         # GET /users         -> {controller => 'users', action => 'index'}
866         # GET /users/create  -> {controller => 'users', action => 'create'}
867         # POST /users        -> {controller => 'users', action => 'store'}
868         # GET /users/23      -> {controller => 'users', action => 'show', id => 23}
869         # GET /users/23/edit -> {controller => 'users', action => 'edit', id => 23}
870         # PUT /users/23      -> {controller => 'users', action => 'update', id => 23}
871         # DELETE /users/23   -> {controller => 'users', action => 'remove', id => 23}
872         $r->resource('users');
873
874   Rearranging routes
875       From application startup until the first request has arrived, all
876       routes can still be moved around or even removed with methods like
877       "add_child" in Mojolicious::Routes::Route and "remove" in
878       Mojolicious::Routes::Route.
879
880         # GET /example/show -> {controller => 'example', action => 'show'}
881         my $show = $r->get('/show')->to('example#show');
882         $r->any('/example')->add_child($show);
883
884         # Nothing
885         $r->get('/secrets/show')->to('secrets#show')->name('show_secrets');
886         $r->find('show_secrets')->remove;
887
888       Especially for rearranging routes created by plugins this can be very
889       useful, to find routes by their name you can use "find" in
890       Mojolicious::Routes::Route.
891
892         # GET /example/test -> {controller => 'example', action => 'test'}
893         $r->get('/something/else')->to('something#else')->name('test');
894         my $test = $r->find('test');
895         $test->pattern->parse('/example/test');
896         $test->pattern->defaults({controller => 'example', action => 'test'});
897
898       Even the route pattern and destination can still be changed with
899       "parse" in Mojolicious::Routes::Pattern and "defaults" in
900       Mojolicious::Routes::Pattern.
901
902   Adding conditions
903       You can also add your own conditions with the method "add_condition" in
904       Mojolicious::Routes. All conditions are basically router plugins that
905       run every time a new request arrives, and which need to return a true
906       value for the route to match.
907
908         # A condition that randomly allows a route to match
909         $r->add_condition(random => sub {
910           my ($route, $c, $captures, $num) = @_;
911
912           # Loser
913           return undef if int rand $num;
914
915           # Winner
916           return 1;
917         });
918
919         # /maybe (25% chance)
920         $r->get('/maybe')->over(random => 4)->to('foo#bar');
921
922       Use whatever request information you need.
923
924         # A condition to check query parameters (useful for mock web services)
925         $r->add_condition(query => sub {
926           my ($route, $c, $captures, $hash) = @_;
927
928           for my $key (keys %$hash) {
929             my $param = $c->req->url->query->param($key);
930             return undef unless defined $param && $param eq $hash->{$key};
931           }
932
933           return 1;
934         });
935
936         # /hello?to=world&test=1
937         $r->get('/hello')->over(query => {test => 1, to => 'world'})->to('foo#bar');
938
939   Condition plugins
940       You can also package your conditions as reusable plugins.
941
942         # Plugin
943         package Mojolicious::Plugin::WerewolfCondition;
944         use Mojo::Base 'Mojolicious::Plugin';
945
946         use Astro::MoonPhase;
947
948         sub register {
949           my ($self, $app) = @_;
950
951           # Add "werewolf" condition
952           $app->routes->add_condition(werewolf => sub {
953             my ($route, $c, $captures, $days) = @_;
954
955             # Keep the werewolves out!
956             return undef if abs(14 - (phase(time))[2]) > ($days / 2);
957
958             # It's ok, no werewolf
959             return 1;
960           });
961         }
962
963         1;
964
965       Now just load the plugin and you are ready to use the condition in all
966       your applications.
967
968         # Application
969         package MyApp;
970         use Mojo::Base 'Mojolicious';
971
972         sub startup {
973           my $self = shift;
974
975           # Plugin
976           $self->plugin('WerewolfCondition');
977
978           # /hideout (keep them out for 4 days after full moon)
979           $self->routes->get('/hideout')->over(werewolf => 4)
980             ->to(controller => 'foo', action => 'bar');
981         }
982
983         1;
984
985   Mount applications
986       The easiest way to embed one application into another is
987       Mojolicious::Plugin::Mount, which allows you to mount whole self-
988       contained applications under a domain and/or prefix.
989
990         use Mojolicious::Lite;
991
992         # Whole application mounted under "/prefix"
993         plugin Mount => {'/prefix' => '/home/sri/myapp.pl'};
994
995         # Mount application with subdomain
996         plugin Mount => {'test.example.com' => '/home/sri/myapp2.pl'};
997
998         # Normal route
999         get '/' => sub { shift->render(text => 'Hello World!') };
1000
1001         app->start;
1002
1003   Embed applications
1004       For a little more power you can also embed applications by using them
1005       instead of a controller. This allows for example, the use of the
1006       Mojolicious::Lite domain specific language in normal Mojolicious
1007       controllers.
1008
1009         # Controller
1010         package MyApp::Controller::Bar;
1011         use Mojolicious::Lite;
1012
1013         # /hello
1014         get '/hello' => sub {
1015           my $c    = shift;
1016           my $name = $c->param('name');
1017           $c->render(text => "Hello $name.");
1018         };
1019
1020         1;
1021
1022       With the method "detour" in Mojolicious::Routes::Route which is very
1023       similar to "to" in Mojolicious::Routes::Route, you can allow the route
1024       to partially match and use only the remaining path in the embedded
1025       application, the base path will be passed along in the "path" stash
1026       value.
1027
1028         # /foo/*
1029         $r->any('/foo')->detour('bar#', name => 'Mojo');
1030
1031       A minimal embeddable application is nothing more than a subclass of
1032       Mojolicious, containing a "handler" method accepting
1033       Mojolicious::Controller objects.
1034
1035         package MyApp::Controller::Bar;
1036         use Mojo::Base 'Mojolicious';
1037
1038         sub handler {
1039           my ($self, $c) = @_;
1040           $c->res->code(200);
1041           my $name = $c->param('name');
1042           $c->res->body("Hello $name.");
1043         }
1044
1045         1;
1046
1047       The host application will only share very little information with the
1048       embedded application through the stash. So you cannot currently use
1049       route placeholders in routes leading to embedded applications, since
1050       that would cause problems with "url_for" in Mojolicious::Controller.
1051
1052   Application plugins
1053       You can even package applications as self-contained reusable plugins.
1054
1055         # Plugin
1056         package Mojolicious::Plugin::MyEmbeddedApp;
1057         use Mojo::Base 'Mojolicious::Plugin';
1058
1059         sub register {
1060           my ($self, $app) = @_;
1061
1062           # Automatically add route
1063           $app->routes->any('/foo')->detour(app => EmbeddedApp::app());
1064         }
1065
1066         package EmbeddedApp;
1067         use Mojolicious::Lite;
1068
1069         get '/bar' => 'bar';
1070
1071         1;
1072         __DATA__
1073         @@ bar.html.ep
1074         Hello World!
1075
1076       The "app" stash value, which won't be inherited by nested routes, can
1077       be used for already instantiated applications. Now just load the plugin
1078       and you're done.
1079
1080         # Application
1081         package MyApp;
1082         use Mojo::Base 'Mojolicious';
1083
1084         sub startup {
1085           my $self = shift;
1086
1087           # Plugin
1088           $self->plugin('MyEmbeddedApp');
1089         }
1090
1091         1;
1092

MORE

1094       You can continue with Mojolicious::Guides now or take a look at the
1095       Mojolicious wiki <http://github.com/mojolicious/mojo/wiki>, which
1096       contains a lot more documentation and examples by many different
1097       authors.
1098

SUPPORT

1100       If you have any questions the documentation might not yet answer, don't
1101       hesitate to ask on the mailing list
1102       <http://groups.google.com/group/mojolicious> or the official IRC
1103       channel "#mojo" on "irc.freenode.net" (chat now!
1104       <https://kiwiirc.com/nextclient/#irc://irc.freenode.net/mojo?nick=guest-?>).
1105
1106
1107
1108perl v5.30.1                      2020-01-30   Mojolicious::Guides::Routing(3)
Impressum