如何为所有传入的URL创建公共处理程序?

时间:2015-10-07 12:32:27

标签: perl mojolicious mojolicious-lite

我正在编写一些web api,它以JSON格式返回数据。

对于所有传入的URL,如果缓存周期没有到期,我需要从缓存中返回一些结果。

此逻辑适用于所有网址。

问题:

如何在Mojolicious :: Lite中为所有传入的URL实现一些通用逻辑?

我试着做

any '/:bar' => [bar => qr/.+/] => sub {
 # ...
 # Return JSON object immediately from cache if it is applicable
 # ...
}

但是这会导致很长的页面加载和

Template "bar.html.ep" not found
在morbo日志中

(但是在经过很长时间的延迟后,最终会执行“/ target”处理程序。)

我是Mojo的完美新手,所以任何帮助都会受到赞赏

谢谢!

2 个答案:

答案 0 :(得分:2)

是的,before_dispatch挂钩似乎是正确的方法,它确实适用于Mojolicious::Lite。这是一个概念验证,它将为每个唯一请求生成一个新结果,但返回重复请求的重复结果。在此程序中,常规请求处理程序会填充缓存,但如果您想将该部分与代码的主要功能分开,则可以在after_dispatch挂钩中执行缓存。

use Mojolicious::Lite;

our %CACHE;

any '/:any' => sub {
    my $self = shift;
    my $param = $self->param('any');
    my $result = { reqtime => time, param => $param, number => rand };
    my $path = $self->req->url->path->to_string;
    $CACHE{$path} //= $result;
    $self->render( json => $result );
};

app->hook( before_dispatch => sub {
    my $c = shift;
    my $path = $c->req->url->path->to_string;
    if (defined($CACHE{$path})) {
        $c->render( json => $CACHE{$path}, status => 200 );
    }
} );
app->secrets([42])->start;

示例运行:

$ morbo cachedemo.pl >/dev/null 2>&1 &

$ for req in foo foo1 foo2 foo3 foo foo1
> do curl http://localhost:3000/$req ; echo ; sleep 1 ; done

{"number":0.848003210075227,"reqtime":1444254617,"param":"foo"}
{"number":0.0745738560703799,"reqtime":1444254618,"param":"foo1"}
{"number":0.484934245556467,"reqtime":1444254619,"param":"foo2"}
{"number":0.181112856445004,"reqtime":1444254620,"param":"foo3"}
{"number":0.848003210075227,"reqtime":1444254617,"param":"foo"}     <-- dup
{"number":0.0745738560703799,"reqtime":1444254618,"param":"foo1"}   <-- dup

答案 1 :(得分:1)

你可以使用*占位符。看here

还将您的应用程序放入开发人员mode

Mojolicious->new( mode => 'developer' );
$app->mode( 'developer');

你会得到相当多的404,500页,这对你很有帮助