1
2=encoding utf8
3
4=head1 NAME
5
6Mojolicious::Guides::Routing - Routing requests
7
8=head1 OVERVIEW
9
10This document contains a simple and fun introduction to the L<Mojolicious> router and its underlying concepts.
11
12=head1 CONCEPTS
13
14Essentials every L<Mojolicious> developer should know.
15
16=head2 Dispatcher
17
18The foundation of every web framework is a tiny black box connecting incoming requests with code generating the
19appropriate response.
20
21  GET /user/show/1 -> $c->render(text => 'Daniel');
22
23This black box is usually called a dispatcher. There are many implementations using different strategies to establish
24these connections, but pretty much all are based around mapping the path part of the request URL to some kind of
25response generator.
26
27  /user/show/2 -> $c->render(text => 'Isabell');
28  /user/show/3 -> $c->render(text => 'Sara');
29  /user/show/4 -> $c->render(text => 'Stefan');
30  /user/show/5 -> $c->render(text => 'Fynn');
31
32While it is very well possible to make all these connections static, it is also rather inefficient. That's why regular
33expressions are commonly used to make the dispatch process more dynamic.
34
35  qr!/user/show/(\d+)! -> $c->render(text => $users{$1});
36
37Modern dispatchers have pretty much everything HTTP has to offer at their disposal and can use many more variables than
38just the request path, such as request method and headers like C<Host>, C<User-Agent> and C<Accept>.
39
40  GET /user/show/23 HTTP/1.1
41  Host: mojolicious.org
42  User-Agent: Mojolicious (Perl)
43  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
44
45=head2 Routes
46
47While regular expressions are quite powerful they also tend to be unpleasant to look at and are generally overkill for
48ordinary path matching.
49
50  qr!/user/admin/(\d+)! -> $c->render(text => $users{$1});
51
52This is where routes come into play, they have been designed from the ground up to represent paths with placeholders.
53
54  /user/admin/:id -> $c->render(text => $users{$id});
55
56The only difference between a static path and the route above is the C<:id> placeholder. One or more placeholders can
57be anywhere in the route.
58
59  /user/:role/:id
60
61A fundamental concept of the L<Mojolicious> router is that extracted placeholder values are turned into a hash.
62
63  /user/admin/23 -> /user/:role/:id -> {role => 'admin', id => 23}
64
65This hash is basically the center of every L<Mojolicious> application, you will learn more about this later on.
66Internally, routes get compiled to regular expressions, so you can get the best of both worlds with a little bit of
67experience.
68
69  /user/admin/:id -> qr/(?-xism:^\/user\/admin\/([^\/.]+))/
70
71A trailing slash in the path is always optional.
72
73  /user/admin/23/ -> /user/:role/:id -> {role => 'admin', id => 23}
74
75=head2 Reversibility
76
77One more huge advantage routes have over regular expressions is that they are easily reversible, extracted placeholders
78can be turned back into a path at any time.
79
80  /sebastian -> /:name -> {name => 'sebastian'}
81  {name => 'sebastian'} -> /:name -> /sebastian
82
83Every placeholder has a name, even if it's just an empty string.
84
85=head2 Standard placeholders
86
87Standard placeholders are the simplest form of placeholders, they use a colon prefix and match all characters except
88C</> and C<.>, similar to the regular expression C<([^/.]+)>.
89
90  /hello              -> /:name/hello -> undef
91  /sebastian/23/hello -> /:name/hello -> undef
92  /sebastian.23/hello -> /:name/hello -> undef
93  /sebastian/hello    -> /:name/hello -> {name => 'sebastian'}
94  /sebastian23/hello  -> /:name/hello -> {name => 'sebastian23'}
95  /sebastian 23/hello -> /:name/hello -> {name => 'sebastian 23'}
96
97All placeholders can be surrounded by C<E<lt>> and C<E<gt>> to separate them from 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
106The colon prefix is optional for standard placeholders that are surrounded by C<E<lt>> and C<E<gt>>.
107
108  /i♥mojolicious -> /<one>♥<two> -> {one => 'i', two => 'mojolicious'}
109
110=head2 Relaxed placeholders
111
112Relaxed placeholders are just like standard placeholders, but use a hash prefix and match all characters except C</>,
113similar to the regular expression C<([^/]+)>.
114
115  /hello              -> /#name/hello -> undef
116  /sebastian/23/hello -> /#name/hello -> undef
117  /sebastian.23/hello -> /#name/hello -> {name => 'sebastian.23'}
118  /sebastian/hello    -> /#name/hello -> {name => 'sebastian'}
119  /sebastian23/hello  -> /#name/hello -> {name => 'sebastian23'}
120  /sebastian 23/hello -> /#name/hello -> {name => 'sebastian 23'}
121
122They can be especially useful for manually matching file names with extensions, rather than using L<format
123detection|/"Formats">.
124
125  /music/song.mp3 -> /music/#filename -> {filename => 'song.mp3'}
126
127=head2 Wildcard placeholders
128
129Wildcard placeholders are just like the two types of placeholders above, but use an asterisk prefix and match
130absolutely everything, including C</> and C<.>, similar to the regular expression C<(.+)>.
131
132  /hello              -> /*name/hello -> undef
133  /sebastian/23/hello -> /*name/hello -> {name => 'sebastian/23'}
134  /sebastian.23/hello -> /*name/hello -> {name => 'sebastian.23'}
135  /sebastian/hello    -> /*name/hello -> {name => 'sebastian'}
136  /sebastian23/hello  -> /*name/hello -> {name => 'sebastian23'}
137  /sebastian 23/hello -> /*name/hello -> {name => 'sebastian 23'}
138
139They can be useful for manually matching entire file paths.
140
141  /music/rock/song.mp3 -> /music/*filepath -> {filepath => 'rock/song.mp3'}
142
143=head1 BASICS
144
145Most commonly used features every L<Mojolicious> developer should know about.
146
147=head2 Minimal route
148
149The attribute L<Mojolicious/"routes"> contains a router you can use to generate route structures.
150
151  # Application
152  package MyApp;
153  use Mojo::Base 'Mojolicious', -signatures;
154
155  sub startup ($self) {
156    # Router
157    my $r = $self->routes;
158
159    # Route
160    $r->get('/welcome')->to(controller => 'foo', action => 'welcome');
161  }
162
163  1;
164
165The minimal route above will load and instantiate the class C<MyApp::Controller::Foo> and call its C<welcome> method.
166Routes are usually configured in the C<startup> method of the application class, but the router can be accessed from
167everywhere (even at runtime).
168
169  # Controller
170  package MyApp::Controller::Foo;
171  use Mojo::Base 'Mojolicious::Controller', -signatures;
172
173  # Action
174  sub welcome ($self) {
175    # Render response
176    $self->render(text => 'Hello there.');
177  }
178
179  1;
180
181All routes match in the same order in which they were defined, and matching stops as soon as a suitable route has been
182found. So you can improve the routing performance by declaring your most frequently accessed routes first. A routing
183cache will also be used automatically to handle sudden traffic spikes more gracefully.
184
185=head2 Routing destination
186
187After you start a new route with methods like L<Mojolicious::Routes::Route/"get">, you can also give it a destination
188in the form of a hash using the chained method L<Mojolicious::Routes::Route/"to">.
189
190  # /welcome -> {controller => 'foo', action => 'welcome'}
191  $r->get('/welcome')->to(controller => 'foo', action => 'welcome');
192
193Now if the route matches an incoming request it will use the content of this hash to try and find appropriate code to
194generate a response.
195
196=head2 HTTP methods
197
198There are already shortcuts for the most common HTTP request methods like L<Mojolicious::Routes::Route/"post">, and for
199more control L<Mojolicious::Routes::Route/"any"> accepts an optional array reference with arbitrary request methods as
200first argument.
201
202  # PUT /hello  -> undef
203  # GET /hello  -> {controller => 'foo', action => 'hello'}
204  $r->get('/hello')->to(controller => 'foo', action => 'hello');
205
206  # PUT /hello -> {controller => 'foo', action => 'hello'}
207  $r->put('/hello')->to(controller => 'foo', action => 'hello');
208
209  # POST /hello -> {controller => 'foo', action => 'hello'}
210  $r->post('/hello')->to(controller => 'foo', action => 'hello');
211
212  # GET|POST /bye  -> {controller => 'foo', action => 'bye'}
213  $r->any(['GET', 'POST'] => '/bye')->to(controller => 'foo', action => 'bye');
214
215  # * /whatever -> {controller => 'foo', action => 'whatever'}
216  $r->any('/whatever')->to(controller => 'foo', action => 'whatever');
217
218There is one small exception, C<HEAD> requests are considered equal to C<GET>, but content will not be sent with the
219response even if it is present.
220
221  # GET /test  -> {controller => 'bar', action => 'test'}
222  # HEAD /test -> {controller => 'bar', action => 'test'}
223  $r->get('/test')->to(controller => 'bar', action => 'test');
224
225You can also use the C<_method> query parameter to override the request method. This can be very useful when submitting
226forms with browsers that only support C<GET> and C<POST>.
227
228  # PUT  /stuff             -> {controller => 'baz', action => 'stuff'}
229  # POST /stuff?_method=PUT -> {controller => 'baz', action => 'stuff'}
230  $r->put('/stuff')->to(controller => 'baz', action => 'stuff');
231
232=head2 IRIs
233
234IRIs are handled transparently, that means paths are guaranteed to be unescaped and decoded from bytes to characters.
235
236  # GET /☃ (Unicode snowman) -> {controller => 'foo', action => 'snowman'}
237  $r->get('/☃')->to(controller => 'foo', action => 'snowman');
238
239=head2 Stash
240
241The generated hash of a matching route is actually the center of the whole L<Mojolicious> request cycle. We call it the
242stash, and it persists until a response has been generated.
243
244  # /bye -> {controller => 'foo', action => 'bye', mymessage => 'Bye'}
245  $r->get('/bye')->to(controller => 'foo', action => 'bye', mymessage => 'Bye');
246
247There are a few stash values with special meaning, such as C<controller> and C<action>, but you can generally fill it
248with whatever data you need to generate a response. Once dispatched the whole stash content can be changed at any time.
249
250  sub bye ($self) {
251
252    # Get message from stash
253    my $msg = $self->stash('mymessage');
254
255    # Change message in stash
256    $self->stash(mymessage => 'Welcome');
257  }
258
259For a full list of reserved stash values see L<Mojolicious::Controller/"stash">.
260
261=head2 Nested routes
262
263It is also possible to build tree structures from routes to remove repetitive code. A route with children can't match
264on its own though, only the actual endpoints of these nested routes can.
265
266  # /foo     -> undef
267  # /foo/bar -> {controller => 'foo', action => 'bar'}
268  my $foo = $r->any('/foo')->to(controller => 'foo');
269  $foo->get('/bar')->to(action => 'bar');
270
271The stash is simply inherited from route to route and newer values override old ones.
272
273  # /cats      -> {controller => 'cats', action => 'index'}
274  # /cats/nyan -> {controller => 'cats', action => 'nyan'}
275  # /cats/lol  -> {controller => 'cats', action => 'default'}
276  my $cats = $r->any('/cats')->to(controller => 'cats', action => 'default');
277  $cats->get('/')->to(action => 'index');
278  $cats->get('/nyan')->to(action => 'nyan');
279  $cats->get('/lol');
280
281With a few common prefixes you can also greatly improve the routing performance of applications with many routes,
282because children are only tried if the prefix matched first.
283
284=head2 Special stash values
285
286When the dispatcher sees C<controller> and C<action> values in the stash it will always try to turn them into a class
287and method to dispatch to. The C<controller> value gets converted from C<snake_case> to C<CamelCase> using
288L<Mojo::Util/"camelize"> and appended to one or more namespaces, defaulting to a controller namespace based on the
289application class (C<MyApp::Controller>), as well as the bare application class (C<MyApp>), and these namespaces are
290searched in that order. The action value is not changed at all, so both values are case-sensitive.
291
292  # Application
293  package MyApp;
294  use Mojo::Base 'Mojolicious', -signatures;
295
296  sub startup ($self) {
297    # /bye -> MyApp::Controller::Foo->bye
298    $self->routes->get('/bye')->to(controller => 'foo', action => 'bye');
299  }
300
301  1;
302
303  # Controller
304  package MyApp::Controller::Foo;
305  use Mojo::Base 'Mojolicious::Controller', -signatures;
306
307  # Action
308  sub bye ($self) {
309    # Render response
310    $self->render(text => 'Good bye.');
311  }
312
313  1;
314
315Controller classes are perfect for organizing code in larger projects. There are more dispatch strategies, but because
316controllers are the most commonly used ones they also got a special shortcut in the form of C<controller#action>.
317
318  # /bye -> {controller => 'foo', action => 'bye', mymessage => 'Bye'}
319  $r->get('/bye')->to('foo#bye', mymessage => 'Bye');
320
321During camelization C<-> characters get replaced with C<::>, this allows multi-level C<controller> hierarchies.
322
323  # / -> MyApp::Controller::Foo::Bar->hi
324  $r->get('/')->to('foo-bar#hi');
325
326You can also just specify the C<controller> in CamelCase form instead of snake_case.
327
328  # / -> MyApp::Controller::Foo::Bar->hi
329  $r->get('/')->to('Foo::Bar#hi');
330
331For security reasons the dispatcher will always check if the C<controller> is actually a subclass of
332L<Mojolicious::Controller> or L<Mojo> before dispatching to it.
333
334=head2 Namespaces
335
336You can use the C<namespace> stash value to change the namespace of a whole route with all its children.
337
338  # /bye -> MyApp::MyController::Foo::Bar->bye
339  $r->get('/bye')->to(namespace => 'MyApp::MyController', controller => 'Foo::Bar', action => 'bye');
340
341The C<controller> is always converted from C<snake_case> to C<CamelCase> with L<Mojo::Util/"camelize">, and then
342appended to this C<namespace>.
343
344  # /bye -> MyApp::MyController::Foo::Bar->bye
345  $r->get('/bye')->to('foo-bar#bye', namespace => 'MyApp::MyController');
346
347  # /hey -> MyApp::MyController::Foo::Bar->hey
348  $r->get('/hey')->to('Foo::Bar#hey', namespace => 'MyApp::MyController');
349
350You can also change the default namespaces for all routes in the application with the router attribute
351L<Mojolicious::Routes/"namespaces">, which usually defaults to a namespace based on the application class
352(C<MyApp::Controller>), as well as the bare application class (C<MyApp>).
353
354  $r->namespaces(['MyApp::MyController']);
355
356=head2 Route to callback
357
358The C<cb> stash value, which won't be inherited by nested routes, can be used to bypass controllers and execute a
359callback instead.
360
361  $r->get('/bye')->to(cb => sub ($c) {
362    $c->render(text => 'Good bye.');
363  });
364
365But just like in L<Mojolicious::Lite> you can also pass the callback directly, which usually looks much better.
366
367  $r->get('/bye' => sub ($c) {
368    $c->render(text => 'Good bye.');
369  });
370
371=head2 Named routes
372
373Naming your routes will allow backreferencing in many methods and helpers throughout the whole framework, most of which
374internally rely on L<Mojolicious::Controller/"url_for"> for this.
375
376  # /foo/marcus -> {controller => 'foo', action => 'bar', user => 'marcus'}
377  $r->get('/foo/:user')->to('foo#bar')->name('baz');
378
379  # Generate URL "/foo/marcus" for route "baz" (in previous request context)
380  my $url = $c->url_for('baz');
381
382  # Generate URL "/foo/jan" for route "baz"
383  my $url = $c->url_for('baz', user => 'jan');
384
385  # Generate URL "http://127.0.0.1:3000/foo/jan" for route "baz"
386  my $url = $c->url_for('baz', user => 'jan')->to_abs;
387
388You can assign a name with L<Mojolicious::Routes::Route/"name">, or let the router generate one automatically, which
389would be equal to the route itself without non-word characters, custom names have a higher precedence though.
390
391  # /foo/bar ("foobar")
392  $r->get('/foo/bar')->to('test#stuff');
393
394  # Generate URL "/foo/bar"
395  my $url = $c->url_for('foobar');
396
397To refer to the current route you can use the reserved name C<current> or no name at all.
398
399  # Generate URL for current route
400  my $url = $c->url_for('current');
401  my $url = $c->url_for;
402
403To check or get the name of the current route you can use the helper
404L<Mojolicious::Plugin::DefaultHelpers/"current_route">.
405
406  # Name for current route
407  my $name = $c->current_route;
408
409  # Check route name in code shared by multiple routes
410  $c->stash(button => 'green') if $c->current_route('login');
411
412=head2 Optional placeholders
413
414Extracted placeholder values will simply redefine older stash values if they already exist.
415
416  # /bye -> {controller => 'foo', action => 'bar', mymessage => 'bye'}
417  # /hey -> {controller => 'foo', action => 'bar', mymessage => 'hey'}
418  $r->get('/:mymessage')->to('foo#bar', mymessage => 'hi');
419
420One more interesting effect, a placeholder automatically becomes optional if there is already a stash value of the same
421name present, this works similar to the regular expression C<([^/.]+)?>.
422
423  # / -> {controller => 'foo', action => 'bar', mymessage => 'hi'}
424  $r->get('/:mymessage')->to('foo#bar', mymessage => 'hi');
425
426  # /test/123     -> {controller => 'foo', action => 'bar', mymessage => 'hi'}
427  # /test/bye/123 -> {controller => 'foo', action => 'bar', mymessage => 'bye'}
428  $r->get('/test/:mymessage/123')->to('foo#bar', mymessage => 'hi');
429
430And if two optional placeholders are only separated by a slash, that slash can become optional as well.
431
432=head2 Restrictive placeholders
433
434A very easy way to make placeholders more restrictive are alternatives, you just make a list of possible values, which
435then work similar to the regular expression C<(bender|leela)>.
436
437  # /fry    -> undef
438  # /bender -> {controller => 'foo', action => 'bar', name => 'bender'}
439  # /leela  -> {controller => 'foo', action => 'bar', name => 'leela'}
440  $r->get('/:name' => [name => ['bender', 'leela']])->to('foo#bar');
441
442You can also adjust the regular expressions behind placeholders directly, just make sure not to use C<^> and C<$> or
443capturing groups C<(...)>, because placeholders become part of a larger regular expression internally, non-capturing
444groups C<(?:...)> are fine though.
445
446  # /23   -> {controller => 'foo', action => 'bar', number => 23}
447  # /test -> undef
448  $r->get('/:number' => [number => qr/\d+/])->to('foo#bar');
449
450  # /23   -> undef
451  # /test -> {controller => 'foo', action => 'bar', name => 'test'}
452  $r->get('/:name' => [name => qr/[a-zA-Z]+/])->to('foo#bar');
453
454This way you get easily readable routes and the raw power of regular expressions.
455
456=head2 Placeholder types
457
458And if you have multiple routes using restrictive placeholders you can also turn them into placeholder types with
459L<Mojolicious::Routes/"add_type">.
460
461  # A type with alternatives
462  $r->add_type(futurama_name => ['bender', 'leela']);
463
464  # /fry    -> undef
465  # /bender -> {controller => 'foo', action => 'bar', name => 'bender'}
466  # /leela  -> {controller => 'foo', action => 'bar', name => 'leela'}
467  $r->get('/<name:futurama_name>')->to('foo#bar');
468
469Placeholder types work just like restrictive placeholders, they are just reusable with the
470C<E<lt>placeholder:typeE<gt>> notation.
471
472  # A type adjusting the regular expression
473  $r->add_type(upper => qr/[A-Z]+/);
474
475  # /user/ROOT -> {controller => 'users', action => 'show', name => 'ROOT'}
476  # /user/root -> undef
477  # /user/23   -> undef
478  $r->get('/user/<name:upper>')->to('users#show');
479
480Some types like C<num> are used so commonly that they are available by default.
481
482  # /article/12   -> {controller => 'article', action => 'show', id => 12}
483  # /article/test -> undef
484  $r->get('/article/<id:num>')->to('articles#show');
485
486For a full list of available placeholder types see also L<Mojolicious::Routes/"TYPES">.
487
488=head2 Introspection
489
490The command L<Mojolicious::Command::routes> can be used from the command line to list all available routes together
491with names and underlying regular expressions.
492
493  $ ./myapp.pl routes -v
494  /foo/:name  ....  POST  fooname  ^/foo/([^/.]+)/?(?:\.([^/]+))?$
495  /bar        ..U.  *     bar      ^/bar
496    +/baz     ...W  GET   baz      ^/baz/?(?:\.([^/]+))?$
497  /yada       ....  *     yada     ^/yada/?(?:\.([^/]+))?$
498
499=head2 Under
500
501To share code with multiple nested routes you can use L<Mojolicious::Routes::Route/"under">, because unlike normal
502nested routes, the routes generated with it have their own intermediate destination and result in additional dispatch
503cycles when they match.
504
505  # /foo     -> undef
506  # /foo/bar -> {controller => 'foo', action => 'baz'}
507  #             {controller => 'foo', action => 'bar'}
508  my $foo = $r->under('/foo')->to('foo#baz');
509  $foo->get('/bar')->to('#bar');
510
511The actual action code for this destination needs to return a true value or the dispatch chain will be broken, this can
512be a very powerful tool for authentication.
513
514  # /blackjack -> {cb => sub {...}}
515  #               {controller => 'hideout', action => 'blackjack'}
516  my $auth = $r->under('/' => sub ($c) {
517
518    # Authenticated
519    return 1 if $c->req->headers->header('X-Bender');
520
521    # Not authenticated
522    $c->render(text => "You're not Bender.", status => 401);
523    return undef;
524  });
525  $auth->get('/blackjack')->to('hideout#blackjack');
526
527Broken dispatch chains can be continued by calling L<Mojolicious::Controller/"continue">, this allows for example,
528non-blocking operations to finish before reaching the next dispatch cycle.
529
530  my $maybe = $r->under('/maybe' => sub ($c) {
531
532    # Wait 3 seconds and then give visitors a 50% chance to continue
533    Mojo::IOLoop->timer(3 => sub {
534
535      # Loser
536      return $c->render(text => 'No luck.') unless int rand 2;
537
538      # Winner
539      $c->continue;
540    });
541
542    return undef;
543  });
544  $maybe->get('/')->to('maybe#winner');
545
546Every destination is just a snapshot of the stash at the time the route matched, and only the C<format> value is shared
547by all of them. For a little more power you can introspect the preceding and succeeding destinations with
548L<Mojolicious::Controller/"match">.
549
550  # Action of the fourth dispatch cycle
551  my $action = $c->match->stack->[3]{action};
552
553=head2 Formats
554
555File extensions like C<.html> and C<.txt> at the end of a route can be detected and stored in the stash value C<format>.
556Use a restrictive placeholder to declare the possible values.
557
558  # /foo.txt -> undef
559  # /foo.rss -> {controller => 'foo', action => 'bar', format => 'rss'}
560  # /foo.xml -> {controller => 'foo', action => 'bar', format => 'xml'}
561  $r->get('/foo' => [format => ['rss', 'xml']])->to('foo#bar');
562
563This for example, allows multiple templates in different formats to share the same action code. And just like with
564placeholders you can use a default value to make the format optional.
565
566  # /foo      -> {controller => 'foo', action => 'bar'}
567  # /foo.html -> {controller => 'foo', action => 'bar', format => 'html'}
568  # /foo.txt  -> {controller => 'foo', action => 'bar', format => 'txt'}
569  $r->get('/foo' => [format => ['html', 'txt']])->to('foo#bar', format => undef);
570
571Formats can be inherited by nested routes.
572
573  # /foo      -> {controller => 'foo', action => 'one', format => undef}
574  # /foo.html -> {controller => 'foo', action => 'one', format => 'html'}
575  # /foo.json -> {controller => 'foo', action => 'one', format => 'json'}
576  # /bar      -> {controller => 'bar', action => 'two', format => undef}
577  # /bar.html -> {controller => 'bar', action => 'two', format => 'html'}
578  # /bar.json -> {controller => 'bar', action => 'two', format => 'json'}
579  my $with_format = $r->any('/' => [format => ['html', 'json']])->to(format => undef);
580  $with_format->get('/foo')->to('foo#one');
581  $with_format->get('/bar')->to('bar#two');
582
583A C<format> value can also be passed to L<Mojolicious::Controller/"url_for">.
584
585  # /foo/23.txt -> {controller => 'foo', action => 'bar', id => 23, format => 'txt'}
586  $r->get('/foo/:id')->to('foo#bar')->name('baz');
587
588  # Generate URL "/foo/24.txt" for route "baz"
589  my $url = $c->url_for('baz', id => 24, format => 'txt');
590
591=head2 WebSockets
592
593With the method L<Mojolicious::Routes::Route/"websocket"> you can restrict access to WebSocket handshakes, which are
594normal C<GET> requests with some additional information.
595
596  # /echo (WebSocket handshake)
597  $r->websocket('/echo')->to('foo#echo');
598
599  # Controller
600  package MyApp::Controller::Foo;
601  use Mojo::Base 'Mojolicious::Controller', -signatures;
602
603  # Action
604  sub echo ($self) {
605    $self->on(message => sub ($self, $msg) {
606      $self->send("echo: $msg");
607    });
608  }
609
610  1;
611
612The connection gets established when you respond to the WebSocket handshake request with a C<101> response status,
613which happens automatically if you subscribe to an event with L<Mojolicious::Controller/"on"> or send a message with
614L<Mojolicious::Controller/"send"> right away.
615
616  GET /echo HTTP/1.1
617  Host: mojolicious.org
618  User-Agent: Mojolicious (Perl)
619  Connection: Upgrade
620  Upgrade: websocket
621  Sec-WebSocket-Key: IDM3ODE4NDk2MjA1OTcxOQ==
622  Sec-WebSocket-Version: 13
623
624  HTTP/1.1 101 Switching Protocols
625  Server: Mojolicious (Perl)
626  Date: Tue, 03 Feb 2015 17:08:24 GMT
627  Connection: Upgrade
628  Upgrade: websocket
629  Sec-WebSocket-Accept: SWsp5N2iNxPbHlcOTIw8ERvyVPY=
630
631=head2 Catch-all route
632
633Since routes match in the order in which they were defined, you can catch all requests that did not match in your last
634route with an optional wildcard placeholder.
635
636  # * /*
637  $r->any('/*whatever' => {whatever => ''} => sub ($c) {
638    my $whatever = $c->param('whatever');
639    $c->render(text => "/$whatever did not match.", status => 404);
640  });
641
642=head2 Conditions
643
644Conditions such as C<headers>, C<agent> and C<host> from L<Mojolicious::Plugin::HeaderCondition> can be applied to any
645route with the method L<Mojolicious::Routes::Route/"requires">, and allow even more powerful route constructs.
646
647  # / (Origin: http://perl.org)
648  $r->get('/')->requires(headers => {Origin => qr/perl\.org/})->to('foo#bar');
649
650  # / (Firefox)
651  $r->get('/')->requires(agent => qr/Firefox/)->to('browser-test#firefox');
652
653  # / (Internet Explorer)
654  $r->get('/')->requires(agent => qr/Internet Explorer/)->to('browser-test#ie');
655
656  # http://docs.mojolicious.org/Mojolicious
657  $r->get('/')->requires(host => 'docs.mojolicious.org')->to('perldoc#index');
658
659Just be aware that conditions are too complex for the routing cache, which normally speeds up recurring requests, and
660can therefore reduce performance.
661
662=head2 Hooks
663
664Hooks operate outside the routing system and allow you to extend the framework itself by sharing code with all requests
665indiscriminately through L<Mojolicious/"hook">, which makes them a very powerful tool especially for plugins.
666
667  # Application
668  package MyApp;
669  use Mojo::Base 'Mojolicious', -signatures;
670
671  sub startup ($self) {
672
673    # Check all requests for a "/test" prefix
674    $self->hook(before_dispatch => sub ($c) {
675      $c->render(text => 'This request did not reach the router.') if $c->req->url->path->contains('/test');
676    });
677
678    # These will not be reached if the hook above renders a response
679    my $r = $self->routes;
680    $r->get('/welcome')->to('foo#welcome');
681    $r->post('/bye')->to('foo#bye');
682  }
683
684  1;
685
686Post-processing the response to add or remove headers is a very common use.
687
688  # Make sure static files are cached
689  $app->hook(after_static => sub ($c) {
690    $c->res->headers->cache_control('max-age=3600, must-revalidate');
691  });
692
693  # Remove a default header
694  $app->hook(after_dispatch => sub ($c) {
695    $c->res->headers->remove('Server');
696  });
697
698Same for pre-processing the request.
699
700  # Choose template variant based on request headers
701  $app->hook(before_dispatch => sub ($c) {
702    return unless my $agent = $c->req->headers->user_agent;
703    $c->stash(variant => 'ie') if $agent =~ /Internet Explorer/;
704  });
705
706Or more advanced extensions to add monitoring to your application.
707
708  # Forward exceptions to a web service
709  $app->hook(after_dispatch => sub ($c) {
710    return unless my $e = $c->stash('exception');
711    $c->ua->post('https://example.com/bugs' => form => {exception => $e});
712  });
713
714You can even extend much of the core functionality.
715
716  # Make controller object available to actions as $_
717  $app->hook(around_action => sub ($next, $c, $action, $last) {
718    local $_ = $c;
719    return $next->();
720  });
721
722  # Pass route name as argument to actions
723  $app->hook(around_action => sub ($next, $c, $action, $last) {
724    return $c->$action($c->current_route);
725  });
726
727For a full list of available hooks see L<Mojolicious/"HOOKS">.
728
729=head1 ADVANCED
730
731Less commonly used and more powerful features.
732
733=head2 Shortcuts
734
735To make route generation more expressive, you can also add your own shortcuts with
736L<Mojolicious::Routes/"add_shortcut">.
737
738  # Simple "resource" shortcut
739  $r->add_shortcut(resource => sub ($r, $name) {
740
741    # Prefix for resource
742    my $resource = $r->any("/$name")->to("$name#");
743
744    # Render a list of resources
745    $resource->get('/')->to('#index')->name($name);
746
747    # Render a form to create a new resource (submitted to "store")
748    $resource->get('/create')->to('#create')->name("create_$name");
749
750    # Store newly created resource (submitted by "create")
751    $resource->post->to('#store')->name("store_$name");
752
753    # Render a specific resource
754    $resource->get('/:id')->to('#show')->name("show_$name");
755
756    # Render a form to edit a resource (submitted to "update")
757    $resource->get('/:id/edit')->to('#edit')->name("edit_$name");
758
759    # Store updated resource (submitted by "edit")
760    $resource->put('/:id')->to('#update')->name("update_$name");
761
762    # Remove a resource
763    $resource->delete('/:id')->to('#remove')->name("remove_$name");
764
765    return $resource;
766  });
767
768  # GET /users         -> {controller => 'users', action => 'index'}
769  # GET /users/create  -> {controller => 'users', action => 'create'}
770  # POST /users        -> {controller => 'users', action => 'store'}
771  # GET /users/23      -> {controller => 'users', action => 'show', id => 23}
772  # GET /users/23/edit -> {controller => 'users', action => 'edit', id => 23}
773  # PUT /users/23      -> {controller => 'users', action => 'update', id => 23}
774  # DELETE /users/23   -> {controller => 'users', action => 'remove', id => 23}
775  $r->resource('users');
776
777=head2 Rearranging routes
778
779From application startup until the first request has arrived, all routes can still be moved around or even removed with
780methods like L<Mojolicious::Routes::Route/"add_child"> and L<Mojolicious::Routes::Route/"remove">.
781
782  # GET /example/show -> {controller => 'example', action => 'show'}
783  my $show = $r->get('/show')->to('example#show');
784  $r->any('/example')->add_child($show);
785
786  # Nothing
787  $r->get('/secrets/show')->to('secrets#show')->name('show_secrets');
788  $r->find('show_secrets')->remove;
789
790Especially for rearranging routes created by plugins this can be very useful, to find routes by their name you can use
791L<Mojolicious::Routes::Route/"find">.
792
793  # GET /example/test -> {controller => 'example', action => 'test'}
794  $r->get('/something/else')->to('something#else')->name('test');
795  my $test = $r->find('test');
796  $test->pattern->parse('/example/test');
797  $test->pattern->defaults({controller => 'example', action => 'test'});
798
799Even the route pattern and destination can still be changed with L<Mojolicious::Routes::Pattern/"parse"> and
800L<Mojolicious::Routes::Pattern/"defaults">.
801
802=head2 Adding conditions
803
804You can also add your own conditions with the method L<Mojolicious::Routes/"add_condition">. All conditions are
805basically router plugins that run every time a new request arrives, and which need to return a true value for the route
806to match.
807
808  # A condition that randomly allows a route to match
809  $r->add_condition(random => sub ($route, $c, $captures, $num) {
810
811    # Loser
812    return undef if int rand $num;
813
814    # Winner
815    return 1;
816  });
817
818  # /maybe (25% chance)
819  $r->get('/maybe')->requires(random => 4)->to('foo#bar');
820
821Use whatever request information you need.
822
823  # A condition to check query parameters (useful for mock web services)
824  $r->add_condition(query => sub ($route, $c, $captures, $hash) {
825
826    for my $key (keys %$hash) {
827      my $param = $c->req->url->query->param($key);
828      return undef unless defined $param && $param eq $hash->{$key};
829    }
830
831    return 1;
832  });
833
834  # /hello?to=world&test=1
835  $r->get('/hello')->requires(query => {test => 1, to => 'world'})->to('foo#bar');
836
837=head2 Condition plugins
838
839You can also package your conditions as reusable plugins.
840
841  # Plugin
842  package Mojolicious::Plugin::WerewolfCondition;
843  use Mojo::Base 'Mojolicious::Plugin', -signatures;
844
845  use Astro::MoonPhase;
846
847  sub register ($self, $app, $conf) {
848
849    # Add "werewolf" condition
850    $app->routes->add_condition(werewolf => sub ($route, $c, $captures, $days) {
851
852      # Keep the werewolves out!
853      return undef if abs(14 - (phase(time))[2]) > ($days / 2);
854
855      # It's ok, no werewolf
856      return 1;
857    });
858  }
859
860  1;
861
862Now just load the plugin and you are ready to use the condition in all your applications.
863
864  # Application
865  package MyApp;
866  use Mojo::Base 'Mojolicious', -signatures;
867
868  sub startup ($self) {
869
870    # Plugin
871    $self->plugin('WerewolfCondition');
872
873    # /hideout (keep them out for 4 days after full moon)
874    $self->routes->get('/hideout')->requires(werewolf => 4)->to(controller => 'foo', action => 'bar');
875  }
876
877  1;
878
879=head2 Mount applications
880
881The easiest way to embed one application into another is L<Mojolicious::Plugin::Mount>, which allows you to mount whole
882self-contained applications under a domain and/or prefix.
883
884  use Mojolicious::Lite -signatures;
885
886  # Whole application mounted under "/prefix"
887  plugin Mount => {'/prefix' => '/home/sri/myapp/script/myapp'};
888
889  # Mount application with subdomain
890  plugin Mount => {'test.example.com' => '/home/sri/myapp2.pl'};
891
892  # Normal route
893  get '/' => sub ($c) {
894    $c->render(text => 'Hello World!');
895  };
896
897  app->start;
898
899=head2 Embed applications
900
901For a little more power you can also embed applications by using them instead of a controller. This allows for example,
902the use of the L<Mojolicious::Lite> domain specific language in normal L<Mojolicious> controllers.
903
904  # Controller
905  package MyApp::Controller::Bar;
906  use Mojolicious::Lite -signatures;
907
908  # /hello
909  get '/hello' => sub ($c) {
910    my $name = $c->param('name');
911    $c->render(text => "Hello $name.");
912  };
913
914  1;
915
916With the attribute L<Mojolicious::Routes::Route/"partial">, you can allow the route to partially match and use only the
917remaining path in the embedded application, the base path will be passed along in the C<path> stash value.
918
919  # /foo/*
920  $r->any('/foo')->partial(1)->to('bar#', name => 'Mojo');
921
922A minimal embeddable application is nothing more than a subclass of L<Mojolicious>, containing a C<handler> method
923accepting L<Mojolicious::Controller> objects.
924
925  package MyApp::Controller::Bar;
926  use Mojo::Base 'Mojolicious', -signatures;
927
928  sub handler ($self, $c) {
929    $c->res->code(200);
930    my $name = $c->param('name');
931    $c->res->body("Hello $name.");
932  }
933
934  1;
935
936The host application will only share very little information with the embedded application through the stash. So you
937cannot currently use route placeholders in routes leading to embedded applications, since that would cause problems
938with L<Mojolicious::Controller/"url_for">.
939
940=head2 Application plugins
941
942You can even package applications as self-contained reusable plugins.
943
944  # Plugin
945  package Mojolicious::Plugin::MyEmbeddedApp;
946  use Mojo::Base 'Mojolicious::Plugin', -signatures;
947
948  sub register ($self, $app, $conf) {
949
950    # Automatically add route
951    $app->routes->any('/foo')->partial(1)->to(app => EmbeddedApp::app());
952  }
953
954  package EmbeddedApp;
955  use Mojolicious::Lite;
956
957  get '/bar' => 'bar';
958
959  1;
960  __DATA__
961  @@ bar.html.ep
962  Hello World!
963
964The C<app> stash value, which won't be inherited by nested routes, can be used for already instantiated applications.
965Now just load the plugin and you're done.
966
967  # Application
968  package MyApp;
969  use Mojo::Base 'Mojolicious', -signatures;
970
971  sub startup ($self) {
972
973    # Plugin
974    $self->plugin('MyEmbeddedApp');
975  }
976
977  1;
978
979=head1 MORE
980
981You can continue with L<Mojolicious::Guides> now or take a look at the L<Mojolicious
982wiki|https://github.com/mojolicious/mojo/wiki>, which contains a lot more documentation and examples by many different
983authors.
984
985=head1 SUPPORT
986
987If you have any questions the documentation might not yet answer, don't hesitate to ask in the
988L<Forum|https://forum.mojolicious.org> or the official IRC channel C<#mojo> on C<irc.libera.chat>
989(L<chat now!|https://web.libera.chat/#mojo>).
990
991=cut
992