From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

# ABSTRACT: Class for dispatching request to the appropriate route handler
$Dancer2::Core::Dispatcher::VERSION = '1.1.2';
use Moo;
has apps => (
is => 'rw',
isa => ArrayRef,
default => sub { [] },
);
has apps_psgi => (
is => 'ro',
isa => ArrayRef,
lazy => 1,
builder => '_build_apps_psgi',
);
sub _build_apps_psgi {
my $self = shift;
return [ map +( $_->name, $_->to_app ), @{ $self->apps } ];
}
sub dispatch {
my ( $self, $env ) = @_;
my @apps = @{ $self->apps_psgi };
DISPATCH: while (1) {
for ( my $i = 0; $i < @apps; $i += 2 ) {
my ( $app_name, $app ) = @apps[ $i, $i + 1 ];
my $response = $app->($env);
# check for an internal request
delete Dancer2->runner->{'internal_forward'}
and next DISPATCH;
# the app raised a flag saying it couldn't match anything
# which is different than "I matched and it's a 404"
delete Dancer2->runner->{'internal_404'}
or do {
delete Dancer2->runner->{'internal_request'};
return $response;
};
}
# don't run anymore
delete Dancer2->runner->{'internal_request'};
last;
} # while
# a 404 on all apps, using the first app
my $default_app = $self->apps->[0];
my $request = $default_app->build_request($env);
return $default_app->response_not_found($request)->to_psgi;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Dancer2::Core::Dispatcher - Class for dispatching request to the appropriate route handler
=head1 VERSION
version 1.1.2
=head1 SYNOPSIS
use Dancer2::Core::Dispatcher;
# Create an instance of dispatcher
my $dispatcher = Dancer2::Core::Dispatcher->new( apps => [$app] );
# Dispatch a request
my $resp = $dispatcher->dispatch($env)->to_psgi;
# Capture internal error of a response (if any) after a dispatch
$dispatcher->response_internal_error($app, $error);
# Capture response not found for an application the after dispatch
$dispatcher->response_not_found($env);
=head1 ATTRIBUTES
=head2 apps
The apps is an array reference to L<Dancer2::Core::App>.
=head2 default_content_type
The default_content_type is a string which represents the context of the
request. This attribute is read-only.
=head1 METHODS
=head2 dispatch
The C<dispatch> method accepts the list of applications, hash reference for
the B<env> attribute of L<Dancer2::Core::Request> and optionally the request
object and an env as input arguments.
C<dispatch> returns a response object of L<Dancer2::Core::Response>.
Any before hook and matched route code is wrapped to allow DSL keywords such
as forward and redirect to short-circuit remaining code, returning across
multiple stack frames without having to throw an exception.
=head2 response_internal_error
The C<response_internal_error> takes as input the list of applications and
a variable error and returns an object of L<Dancer2::Core::Error>.
=head2 response_not_found
The C<response_not_found> consumes as input the list of applications and an
object of type L<Dancer2::Core::App> and returns an object
L<Dancer2::Core::Error>.
=head1 AUTHOR
Dancer Core Developers
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2024 by Alexis Sukrieh.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut