I'm in process of writing some web api, which returns data in JSON format.
For all incoming urls i need to return some result from cache if cache period doesnt expire.
This logic is universal for all URLs.
Question:
How to implement some common logic for all incoming URLs in Mojolicious::Lite?
I tried to do
any '/:bar' => [bar => qr/.+/] => sub {
# ...
# Return JSON object immediately from cache if it is applicable
# ...
}
But this leads to very long page loading and
Template "bar.html.ep" not found
in morbo log (but get "/target" handler will be executed finally, after very long delay).
I am a perfect newbie in Mojo, so any help will be appreciated
Thanks!
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
you can use * placeholder. Look here
Also put you application into developer mode:
Mojolicious->new( mode => 'developer' );
$app->mode( 'developer');
You will get pretty 404, 500 pages that will help you very much
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With