Chouette

 view release on metacpan or  search on metacpan

lib/Chouette.pm  view on Meta::CPAN

            return;
        }

        $c->logger->error($err);
        $c->logger->data->{stacktrace} = $_[0];

        $c->respond({ error => 'internal server error' }, 500);
    };
}


sub _do_routing {
    my ($self, $c) = @_;

    my $path = $c->{env}->{PATH_INFO};
    $path = '/' if $path eq '';

    die "404: Not Found" unless $path =~ $self->{route_regexp};

    my $route_params = \%+;

    my $methods = $self->{route_patterns}->{ $self->{route_regexp_assemble}->source($^R) };

    my $method = $c->{env}->{REQUEST_METHOD};

    my $func = $methods->{$method};

    die "405: Method Not Allowed" if !$func;

    $c->{route_params} = $route_params;

    $func->($c);
}



sub generate_token {
    state $generator = Session::Token->new;

    return $generator->get;
}

1;



__END__

=encoding utf-8

=head1 NAME

Chouette - REST API Framework

=head1 DESCRIPTION

L<Chouette> is a framework for making asynchronous HTTP services. It makes some opinionated design choices, but is otherwise fairly flexible.

L<AnyEvent> is used as the glue to connect all the asynchronous libraries, although Chouette depends on L<Feersum> and therefore L<EV> for its event loop. It uses L<Feersum> in PSGI mode so it can use L<Plack> for request parsing, and has support for...

Chouette generally assumes that its input will be C<application/x-www-form-urlencoded>. L<Plack::Request::WithEncoding> is used so that text is properly decoded (we recommend UTF-8 of course). For output, the default is C<application/json> encoded wi...

Chouette apps can optionally load a config file and its format is C<YAML>, loaded with the L<YAML> module. L<Regexp::Assemble> is used for efficient route-dispatch.

The above aside, Chouette's main purpose is to glue together several of my own modules into a cohesive whole. These modules have been designed to work together and I have used them to build numerous services, some of which handle a considerable amoun...

Chouette was extracted from some of these services I have built before, and I have put in the extra effort required so that all the modules work together in the ways they were designed:

=over

=item L<AnyEvent::Task>

Allows us to perform blocking operations without holding up other requests.

=item L<Callback::Frame>

Makes exception handling simple and convenient. You can C<die> anywhere and it will only affect the request being currently handled.

Important note: If you are using 3rd-party libraries that accept callbacks, please understand how L<Callback::Frame> works. You will usually need to pass C<fub {}> instead of C<sub {}> to these libraries. See the L<EXCEPTIONS> section for more detail...

=item L<Session::Token>

For random identifiers such as session tokens (obviously).

=item L<Log::Defer>

Structured logging, properly integrated with L<AnyEvent::Task> so your tasks can log messages into the proper request log contexts.

Note that Chouette also depends on L<Log::Defer::Viz> so C<log-defer-viz> will be available for viewing logs.

=item L<Log::File::Rolling>

Store logs in files and rotate them periodically. Also maintains a current symlink so you can simply run the following in a shell and you'll always see the latest logs as you need them:

    $ log-defer-viz -F /var/myapi/logs/myapi.current.log

=back

Chouette will always depend on L<AnyEvent::Task>, L<Callback::Frame>, L<Session::Token>, and L<Log::Defer> so if your app also uses these modules then it is sufficient to depend on C<Chouette> alone.

Where does the name "Chouette" come from? A L<chouette|http://www.bkgm.com/variants/Chouette.html> is a multi-player, fast-paced backgammon game with lots of stuff going on at once, kind of like an asynchronous REST API server... Hmmm, a bit of a str...


=head1 CHOUETTE OBJECT

To start a server, create a C<Chouette> object. The constructor accepts a hash ref with the following parameters. Most are optional. See the C<bin/myapi> file below for a full example.

=over

=item C<config_defaults>

This hash is where you provide default config values. These values can be overridden by the config file.

You can use the config store for values specific to your application (it is accessible with the C<config> method of the context), but here are the values that C<Chouette> itself looks for:

C<var_dir> - This directory must exist and be writable. C<Chouette> will use this to store log files and L<AnyEvent::Task> sockets.

C<listen> - This is the location the Chouette server will listen on. Examples: C<8080> C<127.0.0.1:8080> C<unix:/var/myapi/myapi.socket>

C<logging.file_prefix> - The prefix for log file names (default is C<app>).



( run in 1.891 second using v1.01-cache-2.11-cpan-d06a3f9ecfd )