Plack
Superglue for Perl Web Frameworks
         Tatsuhiko Miyagawa
           YAPC::NA 2010
Tatsuhiko Miyagawa

• Lives in San Francisco
• Software Engineer @ Six Apart
• http://search.cpan.org/~miyagawa/
• @miyagawa
• http://bulknews.typepad.com/
Web Applications
Hello World
#!/usr/bin/perl
use strict;

print “Content-Type: text/plainrnrn”;
print “Hello World”;
use FCGI;

my $req = FCGI::Request();
while ($req->Accept >= 0) {
  print “Content-Type: text/plainrnrn”;
  print “Hello World”;
}
package HelloWorld;
use strict;
use Apache::RequestRec;
use Apache::RequestIO;
use Apache::Const -compile => qw(OK);

sub handler {
  my $r = shift;

     $r->content_type(‘text/plain’);
     $r->print(“Hello World”);

     return Apache::Const::OK;
}

1;
package HelloWorld;
use base qw(HTTP::Server::Simple::CGI);

sub handle_request {
  my($self, $cgi) = @_;
  print “HTTP/1.0 200 OKrn”;
  print “Content-Type: text/plainrnrn”;
  print “Hello World”;
}

1;
All similar
but slightly different
Painful to support
   all of them :(
There is (was)
one common way
 to do all of this.
#!/usr/bin/perl
use CGI;

my $q = CGI->new;

print $q->header(‘text/plain’);
print “Hello World”;
Happens to work on:
    CGI, FastCGI, mod_perl
  (HTTP::Server::Simple::CGI)
CGI.pm

mod_perl    CGI     fastcgi



Apache       IIS    lighttpd
CGI.pm?
  meh
Frameworks
to the rescue!
Maypole Mason Mojo Sledge Catalyst Spoon
 PageKit AxKit Egg Gantry Continuity Solstice
 Mojolicious Tripletail Konstrukt Reaction Jifty
  Cyclone3 WebGUI OpenInteract Squatting
 Dancer CGI::Application Nanoa Ark Angelos
        Noe Schenker Tatsumaki Amon
Apache2::WebApp Web::Simple Apache2::REST
          SweetPea Hydrant Titanium
MANY
web frameworks
Let’s look how they
handle web servers.
CGI.pm

mod_perl    CGI     fastcgi



Apache       IIS    lighttpd
CGI::Application




Apache             IIS   lighttpd
CGI::Application




             CGI.pm




Apache             IIS   lighttpd
CGI::Application




             CGI.pm

 mod_perl          CGI   fastcgi



Apache             IIS   lighttpd
CGI::Application         Jifty




             CGI.pm

 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd
CGI::Application         Jifty         Catalyst




             CGI.pm

 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd
CGI::Application         Jifty               Catalyst




             CGI.pm                  Catalyst::Engine


 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd
CGI::Application         Jifty               Catalyst




             CGI.pm                  Catalyst::Engine


 mod_perl          CGI     fastcgi



Apache             IIS      lighttpd          nginx
CGI::Application         Jifty               Catalyst




                            CGI.pm                  Catalyst::Engine


                mod_perl          CGI     fastcgi


HTTP::Server
  ::Simple     Apache             IIS      lighttpd          nginx
Mason          CGI::Application         Jifty               Catalyst




                            CGI.pm                  Catalyst::Engine


                mod_perl          CGI     fastcgi


HTTP::Server
  ::Simple     Apache             IIS      lighttpd          nginx
Mason           CGI::Application         Jifty               Catalyst




Mason::CGIHandler
                                 CGI.pm                  Catalyst::Engine


                     mod_perl          CGI     fastcgi


    HTTP::Server
      ::Simple      Apache             IIS      lighttpd          nginx
Gross.
CGI.pm
  Jifty, CGI::Application, Spoon


mod_perl centric
Mason, Sledge, PageKit, WebGUI


       Adapters
  Catalyst, Maypole, Squatting
That was 2008.
Steal great idea
from Python/Ruby
WSGI (Python)
 Rack (Ruby)
WSGI (PEP-333)
Plack at OSCON 2010
# WSGI
def hello(environ, start_response):
 start_response(“200 OK”, [
   (‘Content-Type’, ‘text/plain’)
 ])
 return [“Hello World”]
WSGI
•   Django       •   mod_wsgi

•   Bottle       •   Paste

•   CherryPy     •   gunicorn

•   Tornado      •   uWSGI

•   Pylons       •   wsgiref

•   Flask        •   Google AppEngine
Django              Bottle         Flask        Tornado


                                             WSGI middleware

                             WSGI


             wsgi handlers


Apache     lighttpd          nginx   mod_wsgi          GAE
Rack
Plack at OSCON 2010
# Rack
class Hello
 def call(env)
   return [
     200,
     { “Content-Type” => ”text/plain” },
     [“Hello World”]
   ]
 end
end
Rack
•   Rails       •   Unicorn

•   Merb        •   Thin

•   Sinatra     •   Mongrel

•   Camping     •   Rainbows!

•   Ramaze      •   Phusion Passenger

•   etc.        •   Heroku
Rails              Merb          Sinatra     Ramaze


                                         Rack middleware

                             Rack


             Rack handlers


Apache     lighttpd          Thin    Unicorn      Mongrel
PSGI
Perl Web Server Gateway Interface
Interface
# WSGI
def hello(environ, start_response):
 start_response(“200 OK”, [
   (‘Content-Type’, ‘text/plain’)
 ])
 return [“Hello World”]
# Rack
class Hello
 def call(env)
   return [
     200,
     { “Content-Type” => ”text/plain” },
     [“Hello World”]
   ]
 end
end
# PSGI
my $app = sub {
   my $env = shift;
   return [
      200,
      [ ‘Content-Type’, ‘text/plain’ ],
      [ ‘Hello World’ ],
   ];
};
PSGI application
   code reference
   $app = sub {...};
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

        CGI-like environment variables
         + psgi.input, psgi.errors etc.
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};


        Status code (int.): 200, 404 etc.
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

       Array reference of header pairs:
       [ ‘Content-Type’, ‘text/html’, ... ]
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

      Array reference of content chunks
      Filehandle or IO::Handle-ish obejct
That’s it.
(There’s a callback based streaming interface as well)
# PSGI
my $app = sub {
   my $env = shift;
   return [
      200,
      [ ‘Content-Type’, ‘text/plain’ ],
      [ ‘Hello World’ ],
   ];
};
Now you’ve got
a PSGI application.
PSGI makes it
so simple to:
Write a new Perl
web app & framework
Write a new Perl
 web server
Mason           CGI::Application         Jifty               Catalyst




Mason::CGIHandler
                                 CGI.pm                  Catalyst::Engine


                     mod_perl          CGI     fastcgi


    HTTP::Server
      ::Simple      Apache             IIS      lighttpd          nginx
Catalyst            CGI::App              Jifty        Tatsumaki


                                                    Plack::Middleware

                                PSGI


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI      mod_psgi   Perlbal
PSGI adaptation
Maypole Mason Mojo Sledge Catalyst Spoon PageKit
 AxKit Egg Gantry Continuity Solstice Mojolicious
Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI
  OpenInteract Squatting Dancer CGI::Application
 Nanoa Ark Angelos Noe Schenker Tatsumaki Amon
   Apache2::WebApp Web::Simple Apache2::REST
             SweetPea Hydrant Titanium
Maypole Mason Mojo Sledge Catalyst Spoon PageKit
 AxKit Egg Gantry Continuity Solstice Mojolicious
Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI
  OpenInteract Squatting Dancer CGI::Application
 Nanoa Ark Angelos Noe Schenker Tatsumaki Amon
   Apache2::WebApp Web::Simple Apache2::REST
             SweetPea Hydrant Titanium
Applications
Movable Type 6, WebGUI 8
# Catalyst
use MyApp;

MyApp->setup_engine(‘PSGI’);
my $app = sub { MyApp->run(@_) };

# $app is a PSGI app!
# Jifty
use MyPonyApp;
my $app = MyPonyApp->psgi_app;

# $app is a PSGI app!
# Dancer
use Dancer;

get ‘/’ => sub {
   “Hello World”;
};

dance; # returns a PSGI app!
# Mojolicious::Lite
use Mojolicious::Lite;

get ‘/:name’ => sub {
   my $self = shift;
   $self->render_text(‘Hello!’);
};

app->start; # returns PSGI app
# Web::Simple
use Web::Simple ‘MyApp’;

package MyApp;
dispatch {
  sub(GET) {
    [ 200, [...], [ ‘Hello’ ] ];
  }
};

my $app = MyApp->as_psgi;

# $app is a PSGI app!
perldoc PSGI
If you want to adapt your framework to PSGI.
Plack
“PSGI toolkit”
HTTP::Server::PSGI
 Reference PSGI web server
      bundled in Plack
Plackup
Runs PSGI app instantly from CLI
      (inspired by rackup)
> plackup app.psgi
Plack::Handler
Connects PSGI apps to Web servers
   CGI, FastCGI, Apache, SCGI
PSGI Web Servers
Starman
UNIX Preforking HTTP servers (like Unicorn.rb)
  HTTP/1.1 chunk + keep-alives / Very Fast
Starlet
        Simpler UNIX HTTP/1.0 Server
Best used with Server::Starter and nginx/lighttpd
Twiggy
Non-blocking web server (like Thin.rb)
   based on AnyEvent framework
Corona
Coroutine for each connection based on Coro.pm
HTTP::Server::Simple::PSGI
 Zero-deps other than HTTP::Server::Simple
    Best for embedding PSGI applications
uWSGI
http://projects.unbit.it/uwsgi/
Perlbal plugin
http://github.com/miyagawa/Perlbal-Plugin-PSGI
nginx embedded perl
 http://github.com/yappo/nginx-psgi-patchs
mod_psgi
http://github.com/spiritloose/mod_psgi
evpsgi
http://github.com/sekimura/evpsgi
Feersum
http://github.com/stash/Feersum
Catalyst            CGI::App               Jifty        Tatsumaki


                                                     Plack::Middleware

                                PSGI


    Plack::Handler::* (CGI, FCGI, Apache)


Apache       lighttpd       HTTP::Server::PSGI       mod_psgi     Perlbal


Starman      Twiggy        uWSGI            Corona       evpsgi
Middleware
Plack at OSCON 2010
PSGI Middleware
 Wraps a PSGI application
to add pre/post processing
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

my $mw = sub {
   my $env = shift;
   # do something with $env
   my $res = $app->($env);
   # do something with $res;
   return $res;
};
PSGI Middleware
  coderef -> coderef
 Higher-order functions
Middleware
   Debug, Session, Logger, Runtime, Static, Lint,
   AccessLog, ConditionalGET, ErrorDocument,
StackTrace, Auth::Basic, Auth::Digest, ReverseProxy,
      Refresh, Auth::OAuth, Hippie, Throttle
Plack::Middleware
  reusable and extensible
  Middleware framework
 Plack::Builder DSL in .psgi
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

builder {
  enable “Static”, root => “/htdocs”,
    path => qr!^/static/!;
  enable “Deflater”; # gzip/deflate
  $app;
}
plackup compatible
plackup -e ‘enable “Foo”;’ app.psgi
Middleware
Write once, run in every framework
DEMO
Plack::App::URLMap
    Multiplex multiple apps
 Integrated with Builder DSL
use CatApp;
use CGIApp;

my $c1 = sub { CatApp->run };
my $c2 = sub { CGIApp->run_psgi };

use Plack::Builder;

builder {
  mount “/cat” => $c1;
  mount “/cgi-app” => builder {
    enable “StackTrace”;
    $c2;
  };
}
CGI::PSGI
Easy migration from CGI.pm
CGI::Emulate::PSGI
    CGI::Compile
Easiest migration from CGI scripts (like Registry)
Plack::Request
    like libapreq (Apache::Request)
wrapper APIs for middleware developers
Plack::Test
 Unified interface to write tests
with Mock HTTP and Live HTTP
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi app => $app, client => sub {
   my $cb = shift;
   my $req = GET “http://localhost/foo”;
   my $res = $cb->($req);
   # test $res;
};
use Plack::Test;
use HTTP::Request::Common;
$Plack::Test::Impl = “Server”;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

test_psgi app => $app, client => sub {
   my $cb = shift;
   my $req = GET “http://localhost/foo”;
   my $res = $cb->($req);
   # test $res;
};
Plack::App::*
ready-to-use applications
Plack::App::Directory
   Static content file server
Plack::App::Proxy
    (non-blocking) proxy server
Can be used as reverse proxy as well
Plack::App::CGIBin
mount /cgi-bin as PSGI applications
Plack::App::FCGIDispatcher
   Connect to FCGI daemon
   (even in Ruby, Python, C)
Plack::App::JSP
Runs JavaScript PSGI apps :)
Testimonials
a.k.a. self-promotion
“I love this! It’s exactly the right answer to
 what i was looking for.” - Benjamin Trott
“Wow, this is nothing short of awesome.”
              - Stevan Little
“Plack is so simple, easy and powerful.”
              - Jesse Vincent
“Plack rocks. Miyagawa rocks.”
         - Piers Cawley
“Is he on too many drugs or too few? Either
  way let’s make sure that never changes.”
               - Matt S.Trout
Real World
Plack/PSGI
Plack at OSCON 2010
You should join!
> cpanm Plack
> cpanm Task::Plack
Cloud?
(Heroku, GAE)
Sunaba
http://sunaba.plackperl.org/
Plack at OSCON 2010
Runs on dankogai’s
    Sandbox
You can even try:
 system(“rm -fr /”);
     while (1) { }
Summary

• PSGI is an interface, Plack is the code.
• We have many (pretty fast) PSGI servers.
• We have adapters and tools for most web
  frameworks.
• Use it!
Remember:
Plack is < 1y old
Lots of (exciting)
 things going on.
http://blog.plackperl.org/
http://github.com/miyagawa/Plack
        http://plackperl.org/
      irc://irc.perl.org/#plack
Questions?
Thank you!
Slides: http://slideshare.net/miyagawa

More Related Content

PDF
Building a desktop app with HTTP::Engine, SQLite and jQuery
KEY
Plack at YAPC::NA 2010
KEY
Intro to PSGI and Plack
KEY
Plack perl superglue for web frameworks and servers
KEY
Deploying Plack Web Applications: OSCON 2011
KEY
Plack - LPW 2009
KEY
KEY
PSGI/Plack OSDC.TW
Building a desktop app with HTTP::Engine, SQLite and jQuery
Plack at YAPC::NA 2010
Intro to PSGI and Plack
Plack perl superglue for web frameworks and servers
Deploying Plack Web Applications: OSCON 2011
Plack - LPW 2009
PSGI/Plack OSDC.TW

What's hot (20)

PDF
Plack basics for Perl websites - YAPC::EU 2011
KEY
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
PPTX
PSGI and Plack from first principles
PDF
AnyMQ, Hippie, and the real-time web
PPTX
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
KEY
Web frameworks don't matter
ODP
Modern Perl
KEY
Psgi Plack Sfpm
PDF
A reviravolta do desenvolvimento web
KEY
Sinatra for REST services
PPS
Web Development in Perl
PDF
DevOps tools for everyone - Vagrant, Puppet and Webmin
PPT
Triple Blitz Strike
PDF
Apache Camel in the belly of the Docker whale
PDF
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
PPT
Web::Scraper
PPTX
Webinar: Building Your First App in Node.js
ZIP
Mojolicious
PDF
Ruby HTTP clients comparison
PDF
Apache::LogFormat::Compiler YAPC::Asia 2013 Tokyo LT-Thon
Plack basics for Perl websites - YAPC::EU 2011
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
PSGI and Plack from first principles
AnyMQ, Hippie, and the real-time web
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
Web frameworks don't matter
Modern Perl
Psgi Plack Sfpm
A reviravolta do desenvolvimento web
Sinatra for REST services
Web Development in Perl
DevOps tools for everyone - Vagrant, Puppet and Webmin
Triple Blitz Strike
Apache Camel in the belly of the Docker whale
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Web::Scraper
Webinar: Building Your First App in Node.js
Mojolicious
Ruby HTTP clients comparison
Apache::LogFormat::Compiler YAPC::Asia 2013 Tokyo LT-Thon
Ad

Similar to Plack at OSCON 2010 (20)

KEY
Psgi Plack Sfpm
PDF
Get your teeth into Plack
PDF
Perl ウェブ開発の中世〜CGI と Plack の間〜
KEY
Kansai.pm 10周年記念 Plack/PSGI 入門
PDF
AnyEvent and Plack
ODP
Modern Web Development with Perl
ODP
Choosing a Web Architecture for Perl
PDF
How to build a High Performance PSGI/Plack Server
PDF
Modern Web Development with Perl
PDF
Slides serverside main
PDF
Docs Python Org Howto Webservers Html
PDF
Jsp & Ajax
PDF
Nginx Internals
PDF
Progressive Enhancement using WSGI
PDF
Deploying And Monitoring Rails
PDF
Mojolicious lite
KEY
Le PERL est mort
KEY
Ruby プログラマのための Perl ウェブアプリケーション開発入門 (Perl web development guide for Rubyist )
KEY
Inside Of Mbga Open Platform
PDF
GlassFish v3 Prelude Aquarium Paris
Psgi Plack Sfpm
Get your teeth into Plack
Perl ウェブ開発の中世〜CGI と Plack の間〜
Kansai.pm 10周年記念 Plack/PSGI 入門
AnyEvent and Plack
Modern Web Development with Perl
Choosing a Web Architecture for Perl
How to build a High Performance PSGI/Plack Server
Modern Web Development with Perl
Slides serverside main
Docs Python Org Howto Webservers Html
Jsp & Ajax
Nginx Internals
Progressive Enhancement using WSGI
Deploying And Monitoring Rails
Mojolicious lite
Le PERL est mort
Ruby プログラマのための Perl ウェブアプリケーション開発入門 (Perl web development guide for Rubyist )
Inside Of Mbga Open Platform
GlassFish v3 Prelude Aquarium Paris
Ad

More from Tatsuhiko Miyagawa (16)

PDF
Carton CPAN dependency manager
KEY
cpanminus at YAPC::NA 2010
KEY
CPAN Realtime feed
PDF
Asynchronous programming with AnyEvent
PPT
Remedie OSDC.TW
PDF
Why Open Matters It Pro Challenge 2008
PDF
20 modules i haven't yet talked about
PPT
Web::Scraper for SF.pm LT
PPT
Web Scraper Shibuya.pm tech talk #8
PPT
XML::Liberal
PPT
Test::Base
PPT
Hacking Vox and Plagger
PPT
Plagger the duct tape of internet
PPT
Tilting Google Maps and MissileLauncher
PPT
Writing Pluggable Software
PPT
How we build Vox
Carton CPAN dependency manager
cpanminus at YAPC::NA 2010
CPAN Realtime feed
Asynchronous programming with AnyEvent
Remedie OSDC.TW
Why Open Matters It Pro Challenge 2008
20 modules i haven't yet talked about
Web::Scraper for SF.pm LT
Web Scraper Shibuya.pm tech talk #8
XML::Liberal
Test::Base
Hacking Vox and Plagger
Plagger the duct tape of internet
Tilting Google Maps and MissileLauncher
Writing Pluggable Software
How we build Vox

Recently uploaded (20)

PDF
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
PPTX
Benefits of Physical activity for teenagers.pptx
PDF
1 - Historical Antecedents, Social Consideration.pdf
DOCX
search engine optimization ppt fir known well about this
PDF
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
PDF
NewMind AI Weekly Chronicles – August ’25 Week III
PDF
OpenACC and Open Hackathons Monthly Highlights July 2025
PDF
Five Habits of High-Impact Board Members
PDF
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
PDF
The influence of sentiment analysis in enhancing early warning system model f...
PDF
Zenith AI: Advanced Artificial Intelligence
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
Consumable AI The What, Why & How for Small Teams.pdf
PPTX
Custom Battery Pack Design Considerations for Performance and Safety
PDF
Abstractive summarization using multilingual text-to-text transfer transforme...
PDF
Developing a website for English-speaking practice to English as a foreign la...
PPTX
The various Industrial Revolutions .pptx
PPT
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
Benefits of Physical activity for teenagers.pptx
1 - Historical Antecedents, Social Consideration.pdf
search engine optimization ppt fir known well about this
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
NewMind AI Weekly Chronicles – August ’25 Week III
OpenACC and Open Hackathons Monthly Highlights July 2025
Five Habits of High-Impact Board Members
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
The influence of sentiment analysis in enhancing early warning system model f...
Zenith AI: Advanced Artificial Intelligence
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
A comparative study of natural language inference in Swahili using monolingua...
Consumable AI The What, Why & How for Small Teams.pdf
Custom Battery Pack Design Considerations for Performance and Safety
Abstractive summarization using multilingual text-to-text transfer transforme...
Developing a website for English-speaking practice to English as a foreign la...
The various Industrial Revolutions .pptx
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game

Plack at OSCON 2010