2015-10-07 3 views
5

Sono in procinto di scrivere alcuni web api, che restituisce i dati in formato JSON.Come creare un gestore comune per tutti gli URL in arrivo?

Per tutti gli url in entrata, è necessario restituire alcuni risultati dalla cache se il periodo di cache non scade.

Questa logica è universale per tutti gli URL.

Domanda:

come implementare una logica comune per tutti gli URL in entrata in Mojolicious :: Lite?

ho cercato di fare

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

Ma questo porta alla pagina molto lunga di carico e

Template "bar.html.ep" not found 

nel registro morbo (ma ottenere "/ target" gestore verrà eseguito alla fine, dopo molto tempo ritardo).

Sono un novizio perfetto in Mojo, in modo che qualsiasi aiuto sarà apprezzato

Grazie!

+3

Puoi mostrarci il codice nel gestore? Mojolicious non dovrebbe cercare un modello 'html.ep' per restituire JSON. Il tuo gestore termina con '$ auto-> render (json => $ oggetto)'? – mob

+0

Penso che http://mojolicio.us/perldoc/Mojolicious/Guides/Routing#Hooks potrebbe aiutarmi. Ma è supportato dalla versione Lite di Mojo? .. – drvtiny

risposta

2

Sì, un gancio before_dispatch sembra l'approccio giusto e funziona con Mojolicious::Lite. Ecco un proof-of-concept che produrrà un nuovo risultato per ogni richiesta unica, ma restituirà risultati ripetuti per richieste ripetute. In questo programma, il normale gestore delle richieste popola la cache, ma se si desidera separare quella parte dalle funzioni principali del codice, è possibile eseguire la memorizzazione nella cache in un hook 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; 

esempio di esecuzione:

$ 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.075227,"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.075227,"reqtime":1444254617,"param":"foo"}  <-- dup 
{"number":0.0745738560703799,"reqtime":1444254618,"param":"foo1"} <-- dup 
+0

È incredibile, grazie mille! Non conoscevo la costruzione "// =" in Perl e la possibilità di avviare appication semplicemente come app-> secrets (["somesecret"]) -> start ... Potresti dirmi per favore, come evitare l'esecuzione di after_dispatch agganciare dopo aver eseguito il rendering nel gancio before_dispatch? Grazie in anticipo! – drvtiny

1

è possibile utilizzare * segnaposto. Guarda here

anche mettere voi l'applicazione in sviluppatore mode:

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

Otterrete graziose 404, 500 pagine che vi aiuterà molto

Problemi correlati