NAME
Prancer::Application
SYNOPSIS
This package is where your application should start.
package MyApp;
use Prancer::Application qw(:all);
use parent qw(Prancer::Application);
sub new {
my $class = shift;
my $self = $class->SUPER::new(shift);
# when prancer is instantiated, the programmer has the option to pass
# extra arguments after the handler class name. those arguments will end
# up in here!
#
# of course, you don't have to write a ->new method if you don't want to as
# one is created automatically in Prancer::Application. but that means that
# if you DO create one you must call to ->SUPER::new first and you MUST
# pass the first argument to ->new (after $class) to ->SUPER::new in order
# for Prancer to work correctly.
return $self;
}
sub handle {
my ($self, $env) = @_;
mount('GET', '/', sub {
context->header(set => 'Content-Type', value => 'text/plain');
context->body("hello world");
context->finalize(200);
});
return dispatch;
}
A new instance of this package is created on every request so that request specific fields may be filled in and available. It also means that your code should be as lightweight as possible.
Your class should implement handle
. Two arguments are passed to this method: the instance of your class created for this request and $env
for the request. You probably don't need to use $env
because the methods detailed below should give you everything you need, especially context
.
EXPORTABLE
The following methods are exportable: context
, mount
, dispatch
, config
, logger
, and database
. They can all be exported at once with :all
.
METHODS
By default this package exports nothing. But that makes it difficult to use. You should probably export :all
. That will give you quick access to these methods.
- config
-
Passes through to
Prancer::config
. This is made available for your application. - logger
-
Passes through to
Prancer::logger
. This is made available for your application. - database
-
Passes through to
Prancer::database
. This is made available for your application. - context
-
This gives access to the request context. See Prancer::Context for more information about what that makes available. But here is a short example:
context->header(set => 'Content-Type', value => 'text/plain'); context->body("hello world"); context->finalize(200);
- mount METHOD, PATH, SUB
-
This adds a routed path. Prancer uses Router::Boom::Method to handle routing. If it is not installed then calls to this method will croak. The first argument will always be the method or methods that should match. For example:
mount('GET', ..., ...); mount(['GET','POST'], ..., ...);
The second argument should be the path that will match. For example:
mount(..., '/', ...); mount(..., '/:user', ...); mount(..., '/blog/{year}', ...); mount(..., '/blog/{year}/{month:\d+}', ...); mount(..., '/download/*', ...);
The last argument should be a sub that will run on a successful match. For example:
mount(..., ..., sub { my $captured = shift; context->header(set => 'Content-Type', value => 'text/plain'); context->body("hello world"); context->finalize(200); });
Of course the sub doesn't have to be anonymous and could point to anything. The only argument that gets passed to a sub is a hashref containing what, if anything, was captured in the route. For example:
mount(..., '/', sub { my $captured = shift; # captured = {} }); # :user matches qr{([^/]+)} mount(..., '/:user', sub { my $captured = shift; print $captured->{'user'}; }); # {year} matches qr{([^/]+)} mount(..., '/blog/{year}/{month:\d+}', sub { my $captured = shift; print $captured->{'year'}; print $captured->{'month'}; }); # * matches qr{(.+)} mount(..., '/download/*', sub { my $captured = shift; print $captured->{'*'}; });
Further documentation on how to use routes can be found by reading the docs for Router::Boom and Router::Boom::Method.
- dispatch
-
This should be called at the end of your implementation to
handle
. It will run the configured routes and return a valid PSGI response to the application server. If you do not have Router::Boom installed then calling this method will croak. If you are not using Router::Boom then you should not use this method but should instead have your implementation ofhandle
return a valid PSGI response.