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

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

VERSION

version 0.07

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 turning the caught exception. NOTE: this coderef should return the exception or modified response. Rethrowing the caught exception will produce undesired results.

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.