AnyEvent-HTTPD-Router

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

# DESCRIPTION

AnyEvent::HTTPD::Router is an extension to the [AnyEvent::HTTPD](https://metacpan.org/pod/AnyEvent::HTTPD) module, from
which it is inheriting. It adds the `reg_routes()` method to it.

This module aims to add as little as possible overhead to it while still being
flexible and extendable. It requires the same little dependencies that
[AnyEvent::HTTPD](https://metacpan.org/pod/AnyEvent::HTTPD) uses.

The dispatching for the routes happens first. If no route could be found, or you
do not stop further dispatching with `stop_request()` the registered callbacks
will be executed as well; as if you would use [AnyEvent::HTTPD](https://metacpan.org/pod/AnyEvent::HTTPD). In other
words, if you plan to use routes in your project you can use this module and
upgrade from callbacks to routes step by step.

Routes support http methods, but custom methods
[https://cloud.google.com/apis/design/custom\_methods](https://cloud.google.com/apis/design/custom_methods) can also be used. You
don't need to, of course ;-)

# SYNOPSIS

    use AnyEvent::HTTPD::Router;

    my $httpd       = AnyEvent::HTTPD::Router->new( port => 1337 );

README.md  view on Meta::CPAN

    `AnyEvent::HTTPD::Router` subclasses `AnyEvent::HTTPD` so you can use all
    methods the parent class.

# EVENTS

- no\_route\_found => $request

    When the dispatcher can not find a route that matches on your request, the
    event `no_route_found` will be emitted.

    In the case that routes and callbacks (`reg_cb()`) for paths as used with
    `AnyEvent::HTTPD` are mixed, keep in mind that that `no_route_found` will
    happen before the other path callbacks are executed. So for a
    `404 not found` handler you could do

        $httpd->reg_cb('' => sub {
            my ( $httpd, $req ) = @_;
            $req->respond( [ 404, 'not found', {}, '' ] );
        });

    If you just use `reg_routes()` and don't mix with `reg_cb()` for paths you
    could implement the `404 not found` handler like this:

lib/AnyEvent/HTTPD/Router.pm  view on Meta::CPAN

=head1 DESCRIPTION

AnyEvent::HTTPD::Router is an extension to the L<AnyEvent::HTTPD> module, from
which it is inheriting. It adds the C<reg_routes()> method to it.

This module aims to add as little as possible overhead to it while still being
flexible and extendable. It requires the same little dependencies that
L<AnyEvent::HTTPD> uses.

The dispatching for the routes happens first. If no route could be found, or you
do not stop further dispatching with C<stop_request()> the registered callbacks
will be executed as well; as if you would use L<AnyEvent::HTTPD>. In other
words, if you plan to use routes in your project you can use this module and
upgrade from callbacks to routes step by step.

Routes support http methods, but custom methods
L<https://cloud.google.com/apis/design/custom_methods> can also be used. You
don't need to, of course ;-)

=head1 SYNOPSIS

 use AnyEvent::HTTPD::Router;

 my $httpd       = AnyEvent::HTTPD::Router->new( port => 1337 );

lib/AnyEvent/HTTPD/Router.pm  view on Meta::CPAN


=head1 EVENTS

=over

=item * no_route_found => $request

When the dispatcher can not find a route that matches on your request, the
event C<no_route_found> will be emitted.

In the case that routes and callbacks (C<reg_cb()>) for paths as used with
C<AnyEvent::HTTPD> are mixed, keep in mind that that C<no_route_found> will
happen before the other path callbacks are executed. So for a
C<404 not found> handler you could do

    $httpd->reg_cb('' => sub {
        my ( $httpd, $req ) = @_;
        $req->respond( [ 404, 'not found', {}, '' ] );
    });

If you just use C<reg_routes()> and don't mix with C<reg_cb()> for paths you
could implement the C<404 not found> handler like this:

lib/AnyEvent/HTTPD/Router/DefaultDispatcher.pm  view on Meta::CPAN

sub add_route {
    my $self  = shift;
    my $verbs = shift;
    my $path  = shift;
    my $cb    = shift;

    unless (exists $self->{routes}->{$path}) {
        my @segments = split /\//, $path;
        $self->{routes}->{$path} = {
            segments  => \@segments, # something to improve speed
            callbacks => {},         # method/path => cb mapping
        };
    }

    my $dispatch_entry = $self->{routes}->{$path};
    foreach my $verb (@$verbs) {
        $dispatch_entry->{callbacks}->{$verb} = $cb;
    }
}

sub match {
    my $self    = shift;
    my $httpd   = shift;
    my $req     = shift;
    my $matched = 0;
    my @path    = $req->url->path_segments;
    my $method  = $req->method;

lib/AnyEvent/HTTPD/Router/DefaultDispatcher.pm  view on Meta::CPAN

            $method = $1;
        }
    }

    # sort because we want to have reproducable
    # behaviour for match
    foreach my $path ( sort keys %{ $self->{routes} } ) {
        my $dispatch_entry = $self->{routes}->{$path};

        # step 1: match the method/verb
        if ( my $cb = $dispatch_entry->{callbacks}->{$method} ) {
            # step 2: match the path
            if ( my $variables = _match_paths( \@path, $dispatch_entry->{segments} ) ) {
                $matched = 1;
                $cb->( $httpd, $req, $variables );
                last;
            }
        }
    }
    return $matched;
}



( run in 0.718 second using v1.01-cache-2.11-cpan-d6f9594c0a5 )