The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

AnyEvent::HTTPD::ExtDirect - RPC::ExtDirect gateway for AnyEvent::HTTPD

SYNOPSIS

    use RPC::ExtDirect::Config;
    use AnyEvent::HTTPD::ExtDirect;
    
    # Ext.Direct Action packages go here
    use My::Server::Foo;
    use My::Server::Bar;
    
    my $config = RPC::ExtDirect::Config->new(
        api_path    => '/api',
        router_path => '/router',
        poll_path   => '/events',
    );
    
    my $httpd = AnyEvent::HTTPD::ExtDirect->new( config => $config );
    
    $httpd->run;

DESCRIPTION

This module provides an RPC::ExtDirect gateway implementation for AnyEvent::HTTPD, a simple lightweight event based web server. Unlike other gateways like Plack::Middleware::ExtDirect or CGI::ExtDirect, this module is in fact more of an application server than just a plugin. You can think of it as Plack framework and Plack::Middleware::ExtDirect combined into one package.

That said, the asynchronous event based nature of AnyEvent::HTTPD allows using it both as a standalone application server, and as a part of a larger program that may do other things besides serving Ext.Direct or plain HTTP requests. See "Non-blocking server" below.

If you are not familiar with Ext.Direct, more information can be found in RPC::ExtDirect::Intro.

USAGE

Configuration

To configure an AnyEvent::HTTPD::ExtDirect instance, you will need to create an instance of RPC::ExtDirect::Config with all required options set, and pass it to AnyEvent::HTTPD::ExtDirect constructor to be used. This step is optional; by default the Config instance in the global API instance will be used instead.

Refer to "OPTIONS" in RPC::ExtDirect::Config for the list of configuration options and their default values.

Entry points

AnyEvent::HTTPD::ExtDirect has three main entry points: the API generator, the Router, and the Event Provider. Each of these has to be assigned a unique server side URI that clients will GET/POST requests to. The API generator URI is usually hardcoded in the client; the Router and Event Provider URIs are advertised as a part of the API declaration provided by the API generator.

The entry point URIs are configured with the api_path, router_path, and poll_path Config options as shown in the "SYNOPSIS". These configuration options have default values that will work out of box; refer to RPC::ExtDirect::Config for details.

Non-blocking server

AnyEvent::HTTPD::ExtDirect can be used not only as a standalone event based application server, but also as an embedded Ext.Direct engine in a larger event based application. This is important and is worth repeating: the non-blocking server approach will only work if your application is event based, adhering to AnyEvent conventions!

To use AnyEvent::HTTPD::ExtDirect as a non-blocking server, create an instance of it, prime it by calling "set_callbacks", and save a reference to it:

    my $httpd = AnyEvent::HTTPD::ExtDirect->new( config => $config );
    $httpd->set_callbacks( ... );

Saving a reference to the server instance is important; if you don't save it, the server instance will be destroyed soon after creation, and you will spend a lot of time trying to figure out why it does not accept requests. So, this will not work as expected:

    AnyEvent::HTTPD::ExtDirect->new( ... )->set_callbacks( ... );

Same goes for other AnyEvent(ish) things you may want to create in your application, including file handle read, timed callbacks, etc.

CAVEATS

The considerations below are specific to AnyEvent::HTTPD::ExtDirect:

Host names vs IP addresses

AnyEvent::HTTPD constructor does not perform host name lookup and will break if you pass in a host name string instead of IP address. The only exception is localhost that will be substituted with 127.0.0.1 loopback address.

Environment objects

For this gateway, the environment object is based on AnyEvent::HTTPD::Request. While it does provide the methods described in "ENVIRONMENT OBJECTS" in RPC::ExtDirect, behavior of these methods can be slightly different from other environments.

For example, $env->http() in CGI::ExtDirect will return the list of both environment variables and HTTP headers in upper case, while the same $env->http() in AnyEvent::HTTPD::ExtDirect application will return only HTTP headers, lowercased.

To avoid potential problems, always find the actual header name first and then use it:

    use List::Util qw/ first /;
    
    my ($header) = first { /^Content[-_]Type$/i } $env->http();
    my $value    = $env->http($header) if $header;
    
    ...

OBJECT INTERFACE

AnyEvent::HTTPD::ExtDirect provides several public methods:

new

Constructor. Returns a new AnyEvent::HTTPD::ExtDirect object. Accepts named arguments in a hash or hashref.

Parameters:

api

Optional RPC::ExtDirect::API instance to be used instead of the default global API tree.

config

Optional RPC::ExtDirect::Config instance to be used. If not provided, the Config instance in the API object (either default or passed in "api" parameter) will be used.

router_class_anyevent

Class name to be used instead of the default RPC::ExtDirect::Router when instantiating Router objects in AnyEvent::HTTPD::ExtDirect environment.

eventprovider_class_anyevent

Class name to be used instead of the default RPC::ExtDirect::EventProvider when instantiating EventProvider objects in AnyEvent::HTTPD::ExtDirect environment.

other

Any other parameter will be passed on to the underlying AnyEvent::HTTPD constructor.

set_callbacks

Instance method. Registers Ext.Direct handlers for API generator, Router, and Event Provider with the AnyEvent::HTTPD transport mechanism, effectively "priming" the server instance without entering a blocking wait. Accepts named arguments in a hash.

This method will be called internally by "run" so you do not need to call it explicitly unless you want to use a non-blocking server option. See "Non-blocking server" section above.

Parameters:

api_path

URI on which the API generator should listen to service discovery requests from the clients. Defaults to server Config option of the same name; this parameter mainly exists for testing overrides.

router_path

URI on which the Router should listen to Ext.Direct Method invocation requests. Defaults to server Config option of the same name; this parameter mainly exists for testing overrides.

poll_path

URI on which the Event Provider should listen to Ext.Direct event polling requests. Defaults to server Config option of the same name; this parameter mainly exists for testing overrides.

run

Instance method. Sets the Ext.Direct callbacks with default Config URIs (see "set_callbacks"), and enters a blocking wait by calling underlying AnyEvent::HTTPD's run method.

This method does not accept arguments, and never returns.

ACCESSOR METHODS

For AnyEvent::HTTPD::ExtDirect, the following accessor methods are provided:

api

Return the current RPC::ExtDirect::API instance held in the server object, or set a new one.

config

Return the current RPC::ExtDirect::Config instance held in the server object, or set a new one.

ACKNOWLEDGEMENTS

I would like to thank IntelliSurvey, Inc for sponsoring my work on versions 2.x and 3.x of the RPC::ExtDirect suite of modules.

BUGS AND LIMITATIONS

At this time there are no known bugs in this module. Please report problems to the author, patches are always welcome.

Use Github tracker to open bug reports, this is the easiest and quickest way to get your issue fixed.

COPYRIGHT AND LICENSE

Copyright (c) 2013-2015 Alex Tokarev <tokarev@cpan.org>.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.