Yes, a before_dispatch
hook seems like the right approach, and it does work with Mojolicious::Lite
. Here's a proof-of-concept that will produce a new result for each unique request, but return repeat results for repeated requests. In this program, the regular request handler populates the cache, but if you wanted to separate that part from the main functions of your code you could do the caching in an after_dispatch
hook.
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;
Sample run:
$ 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