NAME

Plack::App::Path::Router::Custom - A Plack component for dispatching with Path::Router

VERSION

version 0.08

SYNOPSIS

use Plack::App::Path::Router::Custom;
use Path::Router;

my $router = Path::Router->new;
$router->add_route('/' =>
    target => sub {
        my ($request) = @_;
        # use the Plack::Request to
        # create a Plack::Response ...
        my $response = $request->new_response( 200 );
        $response->content_type('text/html');
        $response->body('<html><body>HELLO WORLD</body></html>');
    }
);
$router->add_route('/:action/?:id' =>
    validations => {
        id => 'Int'
    },
    target => sub {
        # matches are passed to the target sub ...
        my ($request, $action, $id) = @_;
        # return a PSGI response ...
        [
          200,
          [ 'Content-Type' => 'text/html' ],
          [ '<html><body>', $action, $id, '</body></html>' ]
        ]
    }
);
$router->add_route('/:action/edit/:id' =>
    validations => {
        id => 'Int'
    },
    target => sub {
        my ($r, $action, $id) = @_;
        # return a string (we will wrap
        # it in a PSGI response for you)
        "This is my action($action), and I am editing this id($id)";
    }
);
$router->add_route('/foo' =>
    # target objects are also supported
    # as long as the object responds to
    # the ->execute method
    target => MyApp::Action->new( type => 'FOO' )
);

# now create the Plack app
my $app = Plack::App::Path::Router::Custom->new(
    router => $router,
    new_request => sub {
        my ($env) = @_;
        Plack::Request->new($env)
    },
    target_to_app => sub {
        my ($target) = @_;
        blessed($target) && $target->can('execute')
            ? sub { $target->execute(@_) }
            : $target
    },
    handle_response => sub {
        my ($res, $req) = @_;
        if (!ref($res)) {
            return [ 200, [], [$res] ];
        }
        elsif (blessed($res) && $res->can('finalize')) {
            return $res->finalize;
        }
        else {
            return $res;
        }
    },
);

DESCRIPTION

This is a Plack::Component subclass which creates an endpoint to dispatch using Path::Router.

It is useful when you need a bit more control than is provided by Plack::App::Path::Router or Plack::App::Path::Router::PSGI (those two modules are in fact written in terms of this one). It provides hooks to manipulate how the PSGI env is turned into a request object, how the target is turned into a coderef which accepts a request and returns a response, and how that response is turned back into a valid PSGI response.

By default, the target must be a coderef which accepts a valid PSGI env and returns a valid PSGI response.

ATTRIBUTES

router

This is a required attribute and must be an instance of Path::Router.

new_request

Coderef which takes a PSGI env and returns a request object of some sort. Defaults to just returning the env.

target_to_app

Coderef which takes the target provided by the matched path and returns a coderef which takes a request (as provided by new_request) and the match arguments, and returns something that handle_response can turn into a PSGI response. Defaults to just returning the target.

handle_response

Coderef which takes the response and request and returns a valid PSGI response. Defaults to just returning the given response.

handle_exception

Coderef which takes an exception thrown by the processing of the request and returns a valid PSGI response. Defaults to just rethrowing the caught exception.

BUGS

All complex software has bugs lurking in it, and this module is no exception. If you find a bug please either email me, or add the bug to cpan-RT.

AUTHOR

Stevan Little <stevan.little at iinteractive.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Infinity Interactive.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.