NAME

Plack::Middleware::ExtDirect - RPC::ExtDirect gateway for Plack

SYNOPSIS

In your app.psgi:

use RPC::ExtDirect::Config;

# Ext.Direct Action packages go here
use My::Server::Foo;
use My::Server::Bar;

my $app = sub { ... };

builder {
    my $config = RPC::ExtDirect::Config->new(
        api_path    => '/api',
        router_path => '/router',
        poll_path   => '/events',
    );
                        
    enable 'ExtDirect', config => $config;
    
    $app;
}

DESCRIPTION

This module provides an RPC::ExtDirect gateway implementation for Plack environment. It is packaged as a standard Plack middleware component suitable for using with Plack::Builder.

Plack::Middleware::ExtDirect is recommended to be used with Perl versions 5.12 and newer, for reasons explained below. For Perls older than 5.12, CGI::ExtDirect gateway may be a better choice - especially if you cannot install XS dependent packages.

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

USAGE

Configuration

To configure a Plack::Middleware::ExtDirect instance, you will need to create an instance of RPC::ExtDirect::Config with all required options set, and pass it to Plack::Middleware::ExtDirect constructor via Plack::Builder's enable feature as shown in "SYNOPSIS". 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

Plack::Middleware::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.

CAVEATS

The considerations below are specific to Plack::Middleware::ExtDirect:

API definition in Perls < 5.12

Plack::Loader is using do builtin to load the app.psgi that returns your PSGI application subroutine. In Perls older than 5.12 this does not work as expected with ExtDirect attributes if you use the Action classes in your app.psgi as shown in "SYNOPSIS"; the appropriate attribute handler never gets called and the Methods won't be defined in the global API instance. This problem does not exist with Perl 5.12 and newer.

If you absolutely have to use an old Perl version and Plack environment, there are two ways of dealing with this problem:

  • One way is to switch to dynamic API declaration (see "DEFINING METHODS DYNAMICALLY" in RPC::ExtDirect::API) and pass the resulting API object to Plack::Middleware::ExtDirect constructor in your app.psgi:

    use RPC::ExtDirect::API;
    use RPC::ExtDirect::Config;
    
    use My::Server::Foo;
    use My::Server::Bar;
    
    my $app = sub { ... };
    
    builder {
        my $config = RPC::ExtDirect::Config->new(
            api_path    => '/api',
            router_path => '/router',
            poll_path   => '/events',
        );
        
        my $api = RPC::ExtDirect::API->new_from_hashref(
            config   => $config,
            api_href => {
                'My::Server::Foo' => {
                    methods => { ... },
                },
                'My::Server::Bar' => {
                    methods => { ... },
                },
            },
        });
                            
        enable 'ExtDirect', api => $api;
        
        $app;
    }
  • Another option is to make sure that all packages that provide Ext.Direct Methods - including Poll Handler methods - are loaded before Plack::Runner's run method is called. The easiest way to do this is to copy plackup script and modify it a little to use all relevant modules:

    use strict;
    use Plack::Runner;
    
    # Ext.Direct Action packages go here
    use My::Server::Foo;
    use My::Server::Bar;
    
    my $runner = Plack::Runner->new;
    
    $runner->parse_options(@ARGV);
    $runner->run;

    In fact the code above is about the whole plackup script.

Environment objects

For Plack Ext.Direct gateway, the environment object is based on Plack::Request. While it does provide the same 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 Plack application will return only HTTP headers as they were defined in HTTP spec.

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

Plack::Middleware::ExtDirect does not provide any publicly accessible methods. It is intended to be used with Plack::Builder as shown above.

EXAMPLES

See included Ext JS examples for ideas on what Ext.Direct is and how to use it in Plack applications. The examples are not installed along with the Plack::Middleware::ExtDirect module, and are only available in the examples/ directory of the CPAN distribution.

To run examples type the following in the Plack::Middleware::ExtDirect tarball directory (for Perl 5.12 and newer):

cd examples
plackup app.psgi

If you are using Perl 5.8.x or 5.10.x, type the following instead:

cd examples
perl plackup_oldperl app.psgi

Note that the examples do not require Plack::Middleware::ExtDirect to be installed so you can try them beforehand. That said, this module depends on RPC::ExtDirect being available in @INC so if you don't want to install either module, unpack both RPC::ExtDirect and Plack::Middleware::ExtDirect tarballs to the same directory and use $PERL5LIB to point to RPC::ExtDirect location:

cd examples
PERL5LIB=../../RPC-ExtDirect-3.xx/lib perl plackup_oldperl app.psgi

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

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) 2011-2014 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.

Included ExtJS examples are copyright (c) 2011, Sencha Inc. Example code is used and distributed under GPL 3.0 license as provided by Sencha Inc. See http://www.sencha.com/license