Mojolicious路由(十)
一、内省
命令Mojolicious:: command::routes可以在命令行中使用,列出所有可用的路由以及名称和底层的正则表达式。
$ ./myapp.pl routes -v
/foo/:name .... POST fooname ^/foo/([^/.]+)/?(?:\.([^/]+))?$
/bar ..U. * bar ^/bar
+/baz ...W GET baz ^/baz/?(?:\.([^/]+))?$
/yada .... * yada ^/yada/?(?:\.([^/]+))?$
二、under
要与多个嵌套路由共享代码,可以使用Mojolicious:: routes::Route中的“under”,因为与普通的嵌套路由不同,用它生成的路由有自己的中间目的地,当它们匹配时,会导致额外的调度周期。
# /foo -> undef
# /foo/bar -> {controller => 'foo', action => 'baz'}
# {controller => 'foo', action => 'bar'}
my $foo = $r->under('/foo')->to('foo#baz');
$foo->get('/bar')->to('#bar');
这个目的地的实际操作代码需要返回一个真值,否则分派链将被破坏,这可能是一个非常强大的身份验证工具。
# /blackjack -> {cb => sub {...}}
# {controller => 'hideout', action => 'blackjack'}
my $auth = $r->under('/' => sub ($c) {
# Authenticated
return 1 if $c->req->headers->header('X-Bender');
# Not authenticated
$c->render(text => "You're not Bender.", status => 401);
return undef;
});
$auth->get('/blackjack')->to('hideout#blackjack');
中断的分派链可以通过在Mojolicious::Controller中调用“continue”来继续,例如,这允许非阻塞操作在到达下一个分派周期之前完成。
my $maybe = $r->under('/maybe' => sub ($c) {
# Wait 3 seconds and then give visitors a 50% chance to continue
Mojo::IOLoop->timer(3 => sub {
# Loser
return $c->render(text => 'No luck.') unless int rand 2;
# Winner
$c->continue;
});
return undef;
});
$maybe->get('/')->to('maybe#winner');
在路由匹配时,每个目的地都只是存储点的快照,并且只有format值被所有目的地共享。为了获得更大的功能,我们可以在Mojolicious::Controller中使用“match”来内省前面和后面的目的地。
# Action of the fourth dispatch cycle
my $action = $c->match->stack->[3]{action};