NAME
Plack::Middleware::Cached - Glues a cache to your PSGI application
SYNOPSIS
use Plack::Builder;
use Plack::Middleware::Cached;
my $cache = CHI->new( ... ); # create a cache
builder {
enable 'Cached', # enable caching
cache => $cache, # using this cache
key => 'REQUEST_URI', # using this key from env
env => ['my.a','my.b']; # and cache $env{'my.a'} and $env{'my.b'},
$app;
}
# alternative creation without Plack::Builder
Plack::Middleware::Cached->wrap( $app, cache => $cache );
DESCRIPTION
This module can be used to glue a cache to a PSGI applications or middleware. A cache is an object that provides at least two methods to get and set data, based on a key. Existing cache modules on CPAN include CHI, Cache, and Cache::Cache. Although this module aims at caching PSGI applications, you can use it to cache any function that returns some response object based on a request environment.
Plack::Middleware::Cached is put in front of a PSGI application as middleware. Given a request in form of a PSGI environment E, it either returns the matching response R from its cache, or it passed the request to the wrapped application, and stores the application's response in the cache:
________ _____
Request ===E===>| |---E--->| |
| Cached | | App |
Response <==R====|________|<--R----|_____|
In most cases, only a part of the environment E is relevant to the request. This relevant part is called the caching key. By default, the key is set to the value of REQUEST_URI from the environment E.
Some application may also modify the environment E:
________ _____
Request ===E===>| |---E--->| |
| Cached | | App |
Response <==R+E==|________|<--R+E--|_____|
If needed, you can configure Plack::Middleware::Cached with env to also cache parts of the environment E, as it was returned by the application.
If Plack::Middleware::Cached retrieved a response from the cache, it sets the environment variable plack.middleware.cached
. You can inspect whether a response came from the cache or from the wrapped application like this:
builder {
enable sub {
my $app = shift;
sub {
my $env = shift;
my $res = $app->($env);
if ($env->{'plack.middleware.cached') {
...
}
return $res;
};
};
enable 'Cached', cache => $cache;
$app;
},
Caching delayed/streaming responses is supported as well.
CONFIGURATION
- cache
-
An cache object, which supports the methods
get( $key )
to retrieve an object from cache andset( $key, $object [, @options ] )
to store an object in cache, possibly adjusted by some options. See CHI for a class than can be used to create cache objects. - key
-
Key to map a PSGI environment to a scalar key. By default only the REQUEST_URI variable is used, but you can provide another variable as scalar, a combination of variables as array reference, or a code reference that is called to calculate a key, given a PSGI environment. If this code returns undef, the request is not cached.
- env
-
Name of an environment variable or array reference with multiple variables from the environment that should be cached together with a response.
- set
-
Code reference to determine a policy for storing data in the cache. Each time a response (and possibly environment data) is to be stored in the cache, it is passed to this function. The code is expected to return an array with the response as first value and optional options to the cache's 'set' method as additional values. For instance you can pass an expiration time like this:
set => sub { my ($response, $env) = @_; return ($response, expires_in => '20 min'); }
You can also use this method to skip selected responses from caching:
set => sub { my ($response, $env) = @_; if ( $some_condition_not_to_cache_this_response ) { return; } return $response; }
SEE ALSO
There already are several modules for caching PSGI applications: Plack::Middleware::Cache by Ingy döt Net implements a simple file cache for PSGI responses. Panu Ervamaa created a more general module of same name, available at https://github.com/pnu/Plack-Middleware-Cache.
AUTHOR
Jakob Voß
COPYRIGHT AND LICENSE
This software is copyright (c) 2013 by Jakob Voß.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.