get your teeth into plack
TRANSCRIPT
Getting Your Teeth Into Plack:A short introduction to the
next generation of web service.
Steven LembarkWorkhorse Computing
No! This is not a Listerine ad!
● Sorry, no jingle in the background.● Plack is an interface for web request handlers.● It simplifies the interface to a usable level.● Permits more portable code.● Allows you to focus on your content handler, not
the API specs.
In the beginning...
● Was CGI:– It was simple enough to implement.
– Proved platform and language agnostic.
– Lived outside of the server, with simple variables and print statements moving the data in and out of back-end code.
– Became the standard for most work on the web.
CGI has problems.
● It was designed for shell-ish environments.– Each iteration of the site required re-launching the CGI
“script” as a separate process.
– This caused too much overhead to re-process the source code for every request.
– Let alone the overhead of creating new processes, especially on non-*NIX systems.
● Fixes involved avoiding the re-processing and dodging CGI altogether.
Inside the beast: mod_foobar
● The alternative was ditching all of CGI.● Code moved inside the server itself.
– Apache created the mod_<thingy> interfaces.
– This allowed the code a low-level view of the request and server state to process its requests.
– For example: mod_perl.
● And things seemed good, for a while...
Be careful what you ask for!
● We have probably all dealt with mod_perl by now:– Once you are inside the beast, you have to deal with it.
– All of it.
● Do you really enjoy dealing with circular documentation, fragmentation of objects, details of the HTTP lifecycle within Apache? Then have fun!
● mod_perl code is also largely non-portable.– Even upgrading Apache can cause major headaches.
The search for a better way
● Hardware and O/S performance have improved since 80486's were “modern”.
● We've also learned a few things about how to design objects.
● This led to multiple approaches for layers between apache internals and the request handler code.
● All of them encapsulate specifics of the server.– Avoid all of us re-inventing the interface wheel.
More than one way to do it...
● Catalyst is one approach.● Python & Ruby took another approach with WSGI
& Rack.● Tatsuhiko Miyagawa developed Perl Web Server
Gateway Interface (PSGI) and Plack.– Note that PSGI is not Plack.
Example: PSGI
● Environment arrives as an argument.
● Return
[status, header, body ]
to caller for response.● Note these are
arrayrefs, not hashes.
my $app= sub{ my $env = shift; return [ 200, [ 'ContentType',
'text/plain' ], [ 'HelloWorld' ], ]};
A few nice things
● The encapsulated source “$env” is limited to the current request.– Less likely to get polluted or contain extraneous values
than %ENV in CGI.
– Return values are server and language agnostic.
Meanwhile, back at the server...
● Plack::Handler provides the interface from PSGI to the server internals.– This includes modules for Apache, FCGI, Starman
(Unicorn.rb).
● There are also stand-alone Perly servers– Twiggy Non-blocking, AnyEvent.
– Dancer Tries to simplify things.
– Starlet Simpler server.
– plackup Just runs your code – comes with plack.
What does this mean to you?
● Ever try to debug mod_perl code with printf?● What if your server were pure perl, executable with
“perl -d ...”?– You could fondle the structures interactively.
– Hardwire breakpoints.
– Fix things a whole lot faster...
● perl -d plackup /path/to/your/module;
Example: Dancer
● Callbacks added by location.● Return the content with
options for headers.● That's about all you need.
#!/bin/env perl
use Dancer;
get '/' =>sub{
'Hello World'};
dance;
Catalyst can also handle PSGI
use My::Catalyst::App;
My::Catalyst::App>setup_engine( 'PSGI' );
my $app = sub{
My::Catalyst::App>run( @_ )};
What Plack gets you
● Plack::Handler What your app sees.● plackup Command-line startup.● Plack::Loader Autoload plack servers● Plack::Middleware PSGI Middleware ● Plack::Builder OO Layer under middleware● Plack::Apps● Plack::Test
Simplest case: plackup# read your app from app.psgi file
plackup
# choose .psgi file from ARGV[0] (or with a option) plackup hello.psgi
# switch server implementation with server (or s) plackup server HTTP::Server::Simple port 9090 \ host 127.0.0.1 test.psgi
# use UNIX socket to run FCGI daemon plackup s FCGI listen /tmp/fcgi.sock myapp.psgi
# launch FCGI external server on port 9090 plackup s FCGI port 9090
Having it both ways: #! or plackup
● Debugging or testing are simpler from code run via perl -d.
● PSGI servers are better for real use.
● Have both: Without a caller this runs itself.
if( caller ){ # plackup, twiggy, etc. $server}else{ # standalone application
require Plack::Runner;
my $run = Plack::Runner>new;
$run>parse_options( @ARGV );
$run>run( $server );}
Server code is simple
● With only $env to worry about, extracting the request is easy.
● Standard errors can be canned.● Even the headers are largely re-usable.● Switches on $env offer simple handler branching.
my $server= sub{$DB::single = 1;
my $env = shift; given( $env ){
when( 'fasta' ){
return [
# hand back javascript for viewing Wcurve 200, $canned_hdrz{ js }, $wc>read_seq( $env>{ fasta } )>format ]
}
...return [ 200, [], ['Unhandled Request'] ]
}};
Summary
● PSGI & Plack bring back the simplicity and portability of CGI.– Flexible enough to support a variety of frameworks
above it.
– Portable enough to run on any server.
● Check the references for lots of examples.
References
Leo Lapworth has multiple Slideshare items about Plack:
http://www.slideshare.net/ranguard/plackbasicsforperlwebsitesyapceu2011
Tatsuhiko Miyagawa has good documentation for Plack along with the modules:
http://search.cpan.org/~miyagawa/
Article: Catalyst 5.9: (Less Code, More Plack!)
http://jjnapiorkowski.typepad.com/modernperl/2011/08/catalyst59lesscodemoreplack.html
The main Plack site:
http://plackperl.org/