The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

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, database, template. 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.

template

Passes through to Prancer::template. 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 of handle return a valid PSGI response.