Plack basics for Perl websites - YAPC::EU 2011
Upcoming SlideShare
Loading in...5
×
 

Plack basics for Perl websites - YAPC::EU 2011

on

  • 18,941 views

Run a website with Perl? - you should learn how to use Plack. Most Perl web frameworks support it and it makes your life a lot easier and a lot more fun

Run a website with Perl? - you should learn how to use Plack. Most Perl web frameworks support it and it makes your life a lot easier and a lot more fun

Statistics

Views

Total Views
18,941
Slideshare-icon Views on SlideShare
17,312
Embed Views
1,629

Actions

Likes
18
Downloads
166
Comments
0

16 Embeds 1,629

http://blog.plackperl.org 1482
http://sayperl.org 44
http://blog.briang.org 25
http://lickck.blogspot.tw 24
http://www.sayperl.org 22
http://lickck.blogspot.com 10
http://leapf.org 4
http://draft.blogger.com 4
http://www.linkedin.com 3
http://www.techgig.com 3
http://news.int80.biz 2
https://twitter.com 2
http://twitter.com 1
http://www.onlydoo.com 1
http://lickck.blogspot.jp 1
https://duckduckgo.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial LicenseCC Attribution-NonCommercial License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Plack basics for Perl websites - YAPC::EU 2011 Plack basics for Perl websites - YAPC::EU 2011 Presentation Transcript

    • Plack BasicsLeo Lapworth @ YAPC::EU 2011 Much content from Tatsuhiko Miyagawa’s YAPC::NA 2010 talk
    • What is Plack?
    • What is Plack?“Superglue for Perl 5 Web Frameworks and Web Servers”
    • How will that help me?
    • How will that help me?‣ Flexibility
    • How will that help me?‣ Flexibility‣ Middleware (plugins)
    • How will that help me?‣ Flexibility‣ Middleware (plugins)‣ Apps
    • How will that help me?‣ Flexibility‣ Middleware (plugins)‣ Apps‣ Development
    • How will that help me?‣ Flexibility‣ Middleware (plugins)‣ Apps‣ Development‣ Testing
    • How will that help me?‣ Flexibility‣ Middleware (plugins)‣ Apps‣ Development‣ Testing‣ Deployment
    • How will that help me?‣ Flexibility‣ Middleware (plugins)‣ Apps‣ Development‣ Testing‣ Deployment‣ World peace
    • How will that help me?‣ Flexibility‣ Middleware (plugins)‣ Apps‣ Development‣ Testing‣ Deployment‣ World peace
    • History...
    • Hello World
    • #!/usr/bin/perluse strict;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;
    • use FCGI;my $req = FCGI::Request();while ($req->Accept >= 0) { print “Content-Type: text/plainrnrn”; print “Hello World”;}
    • 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 similarbut slightly different
    • Painful to support all of them 
    • There wasone common way to do all of this.
    • CGI.pm
    • #!/usr/bin/perluse CGI;my $q = CGI->new;print $q->header(‘text/plain’);print “Hello World”;
    • Works under... CGI FastCGI mod_perlHTTP::Server::Simple::CGI
    • CGI.pmmod_perl CGI fastcgiApache IIS lighttpd
    • CGI.pm?
    • CGI.pm? meh
    • Frameworksto the rescue!
    • Catalyst Maypole Mason Mojo Sledge 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 AmonApache2::WebApp Web::Simple Apache2::REST SweetPea Hydrant Titanium
    • Let’s look how theyhandled web servers.
    • CGI.pmmod_perl CGI fastcgiApache IIS lighttpd
    • CGI::ApplicationApache IIS lighttpd
    • CGI::Application CGI.pmApache IIS lighttpd
    • CGI::Application CGI.pm mod_perl CGI fastcgiApache IIS lighttpd
    • CGI::Application Jifty CGI.pm mod_perl CGI fastcgiApache IIS lighttpd
    • CGI::Application Jifty Catalyst CGI.pm mod_perl CGI fastcgiApache IIS lighttpd
    • CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgiApache IIS lighttpd
    • CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgiApache IIS lighttpd nginx
    • CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgiHTTP::Server ::Simple Apache IIS lighttpd nginx
    • Mason CGI::Application Jifty Catalyst CGI.pm Catalyst::Engine mod_perl CGI fastcgiHTTP::Server ::Simple Apache IIS lighttpd nginx
    • Mason CGI::Application Jifty CatalystMason::CGIHandler CGI.pm Catalyst::Engine mod_perl CGI fastcgi HTTP::Server ::Simple Apache IIS lighttpd nginx
    • Gross.
    • CGI.pm Jifty, CGI::Application, Spoonmod_perl centricMason, Sledge, PageKit, WebGUI Adapters Catalyst, Maypole, Squatting
    • That was 2008...
    • Gentleman thief & Double agentMiyagawa
    • Acquired a great idea from Python/Ruby
    • WSGI (Python) Rack (Ruby)
    • WSGI (PEP-333)
    • WSGI Python Frameworks • Django • mod_wsgi • Bottle • Paste • CherryPy • gunicorn • Tornado • uWSGI • Pylons • wsgiref • Flask • Google AppEngine
    • Django Bottle Flask Tornado WSGI middleware WSGI wsgi handlersApache lighttpd nginx mod_wsgi GAE
    • Rack
    • Rack Ruby Frameworks• Rails • Unicorn• Merb • Thin• Sinatra • Mongrel• Camping • Rainbows!• Ramaze • Phusion Passenger• etc. • Heroku
    • Rails Merb Sinatra Ramaze Rack middleware Rack Rack handlersApache lighttpd Thin Unicorn Mongrel
    • Perl ?
    • PSGI Perl ?Perl Web Server Gateway Interface
    • Interface
    • Interface
    • InterfacePSGI != Plack
    • PSGI application code reference $app = sub {...};
    • # PSGI Hello Worldmy $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ];};
    • 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 ];}; HTTP 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 ];}; String, array reference of content chunks, Filehandle or IO::Handle-ish object
    • That’s it.(There’s a callback based streaming interface as well)
    • # PSGImy $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ];};
    • Now you’ve gota PSGI compatible application.
    • Mason CGI::App Jifty CatalystMason::CGIHandler CGI.pm Catalyst::Engine mod_perl CGI fastcgi HTTP::Server ::Simple Apache IIS lighttpd nginx
    • Catalyst CGI::App Jifty Mason 2 Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal
    • Catalyst CGI::App Jifty Mason 2 Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal other PSGI Webservers
    • Web Servers
    • Plack::HandlerConnects PSGI compatible apps to Web servers...
    • FCGIPlack::Handler::FCGI
    • ApachePlack::Handler::Apache1Plack::Handler::Apache2
    • StarmanUNIX Preforking HTTP servers (like Unicorn.rb) HTTP/1.1 chunk + keep-alives / Very Fast
    • HTTP::Server::Simple::PSGI Zero-deps other than HTTP::Server::Simple Best for embedding PSGI applications
    • Twiggy Non-blocking web server (like Thin.rb) based on AnyEvent framework Starlet Simpler UNIX HTTP/1.0 ServerBest used with Server::Starter and nginx/lighttpd
    • Perlbal pluginhttp://github.com/miyagawa/Perlbal-Plugin-PSGI
    • nginx embedded perl http://github.com/yappo/nginx-psgi-patchs
    • mod_psgihttp://github.com/spiritloose/mod_psgi Apache2
    • Corona uWSGICoroutine for each connection http://projects.unbit.it/uwsgi/ based on Coro.pm Feersum evpsgihttp://github.com/stash/Feersum http://github.com/sekimura/evpsgi Gepok http://metacpan/module/Gepok Pure Perl standalone HTTPS First released July 2011
    • Frameworks Apps Your own code Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache)
    • Frameworks Apps Your own code Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi PerlbalStarman Twiggy uWSGI Corona etc, etc
    • 25+ Plack::Handlers
    • Adoption?
    • Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi PerlbalStarman Twiggy uWSGI Corona etc
    • ? Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi PerlbalStarman Twiggy uWSGI Corona etc
    • Catalyst Maypole Mason Mojo Sledge Spoon PageKit AxKit Egg Gantry Continuity Solstice MojoliciousTripletail 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
    • Catalyst Maypole Mason Mojo Sledge Spoon PageKit AxKit Egg Gantry Continuity Solstice MojoliciousTripletail 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
    • PSGI Perl Frameworks• Amon • Hydrant • Schenker• Angelos • Jifty • Sledge• Ark • Mason • Squatting• Catalyst • Maypole • Tatsumaki• CGI::Application • Mojo • Titanium• Continuity • Mojolicious • Web::Simple• Dancer • Noe
    • Applications Movable Type 6 WebGUI 8 RT4 ACT (conference toolkit)Bricolage (if someone gets time)
    • Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi PerlbalStarman Twiggy uWSGI Corona evpsgi
    • Catalyst CGI::App Jifty Tatsumaki Dancer Mojoliscious MT6 Mason 2 Web::Simple WebGui 8 Mojo etc... Plack::Middleware PSGI Compatible App Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi PerlbalStarman Twiggy uWSGI Corona evpsgi
    • PSGI from a framework
    • use Dancer;get ‘/’ => sub { “Hello World”;};dance;
    • use Mojolicious::Lite;get ‘/:name’ => sub { my $self = shift; $self->render_text(‘Hello!’);};app->start;
    • use My::Jifty::App;my $app = My::Jifty::App->psgi_app;
    • use Web::Simple ‘MyApp’;package MyApp;dispatch { sub(GET) { [ 200, [...], [ ‘Hello’ ] ]; }};my $app = MyApp->as_psgi;
    • use My::Catalyst::App;My::Catalyst::App->setup_engine(‘PSGI’);my $app = sub { My::Catalyst::App->run(@_) };
    • catalyst.pl My::Catalyst::App
    • Plack“PSGI implementation & toolkit”
    • Plack toolkit
    • Plack toolkitPlack::Handlers Connect PSGI apps and Web Servers
    • Plack toolkitPlack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher
    • Plack toolkitPlack::Handlers Connect PSGI apps and Web Servers plackup Command line launcherPlack::Loader (auto)load Plack Servers
    • Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack ServersPlack::Middleware Easy-to-use PSGI Middleware
    • Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack ServersPlack::Middleware Easy-to-use PSGI Middleware Plack::Builder OO & DSL to enable Middleware
    • Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack ServersPlack::Middleware Easy-to-use PSGI Middleware Plack::Builder OO & DSL to enable Middleware Plack::Apps Apps
    • Plack toolkit Plack::Handlers Connect PSGI apps and Web Servers plackup Command line launcher Plack::Loader (auto)load Plack ServersPlack::Middleware Easy-to-use PSGI Middleware Plack::Builder OO & DSL to enable Middleware Plack::Apps Apps Plack::Test Testing
    • plackupRuns PSGI app instantly from CLI (inspired by rackup)
    • > plackup app.psgi
    • > plackup app.psgiHTTP::Server::PSGI: Acceptingconnections at http://0:5000/
    • HTTP::Server::PSGI Reference PSGI web server bundled in Plack Standalone, single-process HTTP server great for development and testing
    • Plack::Middleware (160+ modules - July 2011)
    • Middleware Debug, Session, Logger, Static, Lint,AccessLog, ErrorDocument, StackTrace, Auth::Basic, Auth::Digest, ReverseProxy, Refresh, Auth::OAuth, Throttle....
    • Chunked Class::Refresh Compile Conditional ConditionalGETConsoleLogger ContentLength ContentMD5 CrossOriginCSRFBlock Dancer::Debug DBIC::QueryLog DebugDebug::CatalystPluginCache Debug::DBIC::QueryLogDebug::DBIProfile Debug::Profiler::NYTProf Debug::W3CValidateDeflater DoCoMoGUID Doorman ErrorDocument ESI ETagExpires File::Sass Firebug::Lite FirePHP ForceEnv Head HeaderHTMLify HTMLMinify HTTPExceptions IEnosniff IIS6ScriptNameFixImage::Scale Inline InteractiveDebugger IPAddressFilter iPhoneJavaScript::Ectype JSConcat JSONP LighttpdScriptNameFix LintLog::Contextual Log::Minimal Log4perl LogDispatch LogWarnMethodOverride Mirror NeverExpire NoDeflate NoMultipleSlashesNullLogger Options OptionsOK Precompressed ProxyMapRearrangeHeaders Recursive RefererCheck Refresh REPL ReproxyReverseProxy Rewrite Runtime Scope::Container Scope::SessionServerStatus::Lite Session Session::SerializedCookie SetAcceptSimpleContentFilter SimpleLogger SizeLimit SocketIO SSIStackTrace Static Static::Minifier StaticShared StatusTest::StashWarnings Throttle TMT UseChromeFrame Watermark
    • Plack Middleware Wraps a PSGI applicationto add pre/post processing
    • Logging
    • LoggingStatus code redirect
    • LoggingStatus code redirectError Handler
    • LoggingStatus code redirectError HandlerCache Middleware
    • LoggingStatus code redirectError HandlerCache MiddlewareSession Middleware
    • LoggingStatus code redirectError HandlerCache MiddlewareSession MiddlewareRoutes Middleware
    • LoggingStatus code redirectError HandlerCache MiddlewareSession MiddlewareRoutes MiddlewareYour App
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible App
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in P::MW::A
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in P::MW::A P::MW::B
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in P::MW::A P::MW::B PSGI App
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in P::MW::A P::MW::B P::MW::B PSGI App
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in P::MW::A P::MW::A P::MW::B P::MW::B PSGI App
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in Response out P::MW::A P::MW::A P::MW::B P::MW::B PSGI App
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in e.g. Redirect Response out P::MW::A P::MW::A P::MW::B P::MW::B PSGI App
    • Plack::Middleware::A Plack::Middleware::B PSGI Compatible AppRequest in e.g. Redirect Response out P::MW::A P::MW::A e.g. Static P::MW::B P::MW::B PSGI App
    • EnablingPlack::Middleware reusable and extensible Middleware framework Plack::Builder DSL in .psgi
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “A”; enable “B”; $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “A”; enable “B”; $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “A”; enable “B”; $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “A”; enable “B”; $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “A”; # Plack::Middleware::A enable “B”; # Order matters $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “A”; enable “B”; $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; # gzip/deflate $app;}
    • my $app = sub { return [ $status, $header, $body ];};use Plack::Builder;return builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; $app;}
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible App
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in Static
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in Response out =~ ^/static Static
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in Response out =~ ^/static Static -
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in Response out =~ ^/static Static - PSGI App
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in Response out =~ ^/static Static - Deflate compresses PSGI App
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in Response out =~ ^/static Static - - Deflate compresses PSGI App
    • Plack::Middleware::Static Plack::Middleware::Deflate PSGI Compatible AppRequest in Response out =~ ^/static Static - - Deflate compresses PSGI App
    • plackup compatibleplackup -e ‘enable “Foo”;’ app.psgi
    • MiddlewareWrite once, run in every framework
    • A few demos..
    • Assume...use Plack::Builder;my $body = ‘<html><body>Hello World</body></html>’;my $app = sub { my $self = shift; return [200, [Content-Type => text/html], [ $body ]];};
    • Assume...use Plack::Builder;my $body = ‘<html><body>Hello World</body></html>’;my $app = sub { my $self = shift; return [200, [Content-Type => text/html], [ $body ]];};
    • Assume...use Plack::Builder;my $body = ‘<html><body>Hello World</body></html>’;my $app = sub { my $self = shift; return [200, [Content-Type => text/html], [ $body ]];};
    • Debugger
    • return builder { # Precious debug info. Right on your page! enable Debug; $app;}
    • InteractiveDebugger
    • my $app = sub { my $foo = bar; die "oops" if $foo eq bar; [200, [Content-Type => text/html], [ $body ]];};return builder { # Enable Interactive debugging enable "InteractiveDebugger"; $app;}
    • my $app = sub { my $foo = bar; die "oops" if $foo eq bar; [200, [Content-Type => text/html], [ $body ]];};return builder { # Enable Interactive debugging enable "InteractiveDebugger"; $app;}
    • my $app = sub { my $foo = bar; die "oops" if $foo eq bar; [200, [Content-Type => text/html], [ $body ]];};return builder { # Enable Interactive debugging enable "InteractiveDebugger"; $app;}
    • NYTProf - profiler
    • First rule of Program Optimisation
    • Don’t do it!
    • Second rule of Program Optimisation (for experts only)
    • Don’t do it - yet!
    • return builder { enable Debug, panels => [ [ Profiler::NYTProf ] ]; $app;};
    • ServerStatus::Lite
    • use Plack::Builder;return builder { enable "ServerStatus::Lite", path => /server-status, allow => [ 127.0.0.1], scoreboard => /tmp/score; $app;}
    • SizeLimit
    • use Plack::Builder;return builder { enable "SizeLimit", max_unshared_size_in_kb => 3000, check_every_n_requests => 5; $app;}
    • Plack::App::*ready-to-use applications
    • Apache::ActionWrapper CGIBin CascadeCocProxy DAV Directory Directory::XslateFCGIDispatcher File ImageMagick JSP PSGIBinPath::Router ProxyProxy::Backend::AnyEvent::HTTPProxy::Backend::LWP Proxy::Selective Proxy::TestURLMap WrapApacheReqWrapApacheReq::FakeRequest WrapCGI
    • Plack::App::CGIBinmount /cgi-bin as PSGI applications
    • CGI::PSGIEasy migration from CGI.pm
    • Plack::App::Directory Static content file server
    • Plack::App::Proxy (non-blocking) proxy serverCan be used as reverse proxy as well
    • Plack::App::JSPRuns JavaScript PSGI apps :)
    • # app.psgi - Javascript!Plack::App::JSP->new( js => q{ function respond(body) { return [ 200, [ Content-type, text/html ], [ body ] ] } respond("Five factorial is " + (function(x) { if ( x<2 ) return x; return x * arguments.callee(x - 1); })(5) );});
    • # app.psgi - Javascript!Plack::App::JSP->new( js => q{ function respond(body) { return [ 200, [ Content-type, text/html ], [ body ] ] } respond("Five factorial is " + (function(x) { if ( x<2 ) return x; return x * arguments.callee(x - 1); })(5) );});
    • 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;return builder { mount “/cat” => $c1; mount “/cgi-app” => builder { enable “StackTrace”; $c2; };}
    • use CatApp;use CGIApp;my $c1 = sub { CatApp->run };my $c2 = sub { CGIApp->run_psgi };use Plack::Builder;return builder { mount “/cat” => $c1; mount “/cgi-app” => builder { enable “StackTrace”; $c2; };}
    • use CatApp;use CGIApp;my $c1 = sub { CatApp->run };my $c2 = sub { CGIApp->run_psgi };use Plack::Builder;return builder { mount “/cat” => $c1; mount “/cgi-app” => builder { enable “StackTrace”; $c2; };}
    • Some more demos...
    • Basic website
    • TemplateToolkit + Static
    • my $root = /path/to/html_doc_root;my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root,)->to_app;return builder { enable Static, path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app;}
    • my $root = /path/to/html_doc_root;my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root,)->to_app;return builder { enable Static, path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app;}
    • my $root = /path/to/html_doc_root;my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root,)->to_app;return builder { enable Static, path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app;}
    • my $root = /path/to/html_doc_root;my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root,)->to_app;return builder { enable Static, path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app;}
    • my $root = /path/to/html_doc_root;my $app = Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => root,)->to_app;return builder { enable Static, path => qr{.[gif|png|jpg|swf|ico|mov|mp3|pdf|js|css]$}, root => $root; $app;}
    • Creating utilities
    • Caching Proxy
    • Website
    • WebsiteDeveloping code
    • WebsiteDeveloping code
    • Slow website WebsiteDeveloping code
    • Slow websiteDeveloping code
    • Slow website Caching ProxyDeveloping code
    • use Plack::Middleware::Cache;use Plack::App::Proxy;my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app;return builder { enable "Cache", match_url => ^/.*, # everything cache_dir => /tmp/plack-cache; $app;};
    • use Plack::Middleware::Cache;use Plack::App::Proxy;my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app;return builder { enable "Cache", match_url => ^/.*, # everything cache_dir => /tmp/plack-cache; $app;};
    • use Plack::Middleware::Cache;use Plack::App::Proxy;my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app;return builder { enable "Cache", match_url => ^/.*, # everything cache_dir => /tmp/plack-cache; $app;};
    • use LWP::Simple;my $content = get(‘http://localhost:5000/’);
    • Caching Proxy + Domain hijack
    • use LWP::Simple;my $content = get(‘http://localhost:5000/’);
    • use LWP::Simple;my $content = get(‘http://london.pm.org/’);
    • my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app;return builder { enable "Cache", match_url => ^/.*, # everything cache_dir => /tmp/plack-cache2; $app;};
    • my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app;return builder { enable "Cache", match_url => ^/.*, # everything cache_dir => /tmp/plack-cache2; $app;};
    • my $app = Plack::App::Proxy->new( remote => "http://london.pm.org/" )->to_app;$app = builder { enable "Cache", match_url => ^/.*, # everything cache_dir => /tmp/plack-cache2; $app;};
    • # Hijack Any LWP::Useragent requestsLWP::Protocol::PSGI->register($app);use LWP::Simple;my $content = get("http://london.pm.org/");say o/ if $content =~ /London Perl Mongers/;
    • # Hijack Any LWP::Useragent requestsLWP::Protocol::PSGI->register($app);use LWP::Simple;my $content = get("http://london.pm.org/");say o/ if $content =~ /London Perl Mongers/;
    • # Hijack Any LWP::Useragent requestsLWP::Protocol::PSGI->register($app);use LWP::Simple;my $content = get("http://london.pm.org/");say o/ if $content =~ /London Perl Mongers/;
    • # Hijack Any LWP::Useragent requestsLWP::Protocol::PSGI->register($app);use LWP::Simple;my $content = get("http://london.pm.org/");say o/ if $content =~ /London Perl Mongers/;
    • Plack::TestUnified interface to write TAP 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 $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • use Plack::Test;use HTTP::Request::Common;my $app = sub { my $env = shift; return [ $status, $header, $body ];};test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • use Plack::Test;use HTTP::Request::Common;my $app = sub { my $env = shift; return [ $status, $header, $body ];};test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • use Plack::Test;use HTTP::Request::Common;my $app = sub { my $env = shift; return [ $status, $header, $body ];};test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • use Plack::Test;use HTTP::Request::Common;my $app = sub { my $env = shift; return [ $status, $header, $body ];};test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • use Plack::Test;use HTTP::Request::Common;my $app = sub { my $env = shift; return [ $status, $header, $body ];};test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • use Plack::Test;use HTTP::Request::Common;my $app = sub { my $env = shift; return [ $status, $header, $body ];};test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • use Plack::Test;use HTTP::Request::Common;my $app = sub { my $env = shift; return [ $status, $header, $body ];};test_psgi app => $app, client => sub { my $callback = shift; my $req = GET “http://localhost/foo”; my $res = $callback->($req); ok $res->[0] == ‘200’, ‘Success’; };
    • Test::WWW::Mechanize::PSGI
    • use Test::WWW::Mechanize::PSGI; my $mech = Test::WWW::Mechanize::PSGI->new(     app => $app, );$mech->get_ok(/);
    • use Test::WWW::Mechanize::PSGI; my $mech = Test::WWW::Mechanize::PSGI->new(     app => $app, );$mech->get_ok(/);
    • Testing your full configuration!
    • Network setup tip
    • Use a reverse proxy
    • Use a reverse proxy• Sits in front of servers, not clients - “reverse”
    • Use a reverse proxy• Sits in front of servers, not clients - “reverse”• Makes servers more efficient
    • Use a reverse proxy• Sits in front of servers, not clients - “reverse”• Makes servers more efficient• Add HTTPS easily
    • Use a reverse proxy• Sits in front of servers, not clients - “reverse”• Makes servers more efficient• Add HTTPS easily• Makes scaling easier
    • Internet / UsersWebserver App
    • Internet / UsersWebserver App
    • Internet / UsersWebserver App
    • Internet / UsersWebserver App
    • Internet / Users Reverse Proxy NGINX Perlbal PoundWebserver App
    • Internet / Users Reverse Proxy NGINX Perlbal PoundWebserver App
    • Internet / Users Reverse Proxy NGINX Perlbal PoundWebserver App
    • Internet / Users Reverse Proxy NGINX Perlbal PoundWebserver App
    • Internet / Users Reverse Proxy NGINX Perlbal PoundWebserver App
    • Reverse ProxyNGINX Perlbal Pound Server
    • Reverse Proxy NGINX Perlbal PoundServer 1 Server 2
    • Reverse Proxy NGINX Perlbal PoundServer 1 Server 3 Server 2
    • Reverse Proxy NGINX Perlbal PoundServer 1 Server 3 Server 2
    • Plack::Middleware::ReverseProxy Updates $env->{REMOTE_ADDRESS}
    • Why use Plack?
    • Why use Plack?‣ Flexibility‣ Middleware‣ Apps‣ Development‣ Testing‣ Deployment
    • Flexibility Plack::Handler::* (CGI, FCGI, Apache)Apache lighttpd HTTP::Server::PSGI mod_psgi PerlbalStarman Twiggy uWSGI Corona etc
    • Flexibility• Easy to change webserver (25+!) Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc
    • Flexibility• Easy to change webserver (25+!) Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona etc• Starman seems to be used most
    • Middleware
    • Middleware• Easy to reuse with any PSGI app
    • Middleware• Easy to reuse with any PSGI app• Many tools to make your life easy
    • Middleware• Easy to reuse with any PSGI app• Many tools to make your life easy• 160+ on CPAN now
    • App
    • App• URLMapping / Routing
    • App• URLMapping / Routing• Static files
    • App• URLMapping / Routing• Static files• Proxying
    • Development
    • Development• plackup
    • Development• plackup• Restarter (monitor changes on disk)
    • Development• plackup• Restarter (monitor changes on disk)• HTTP::Server::PSGI
    • Development• plackup• Restarter (monitor changes on disk)• HTTP::Server::PSGI• Debugging middleware
    • Development• plackup• Restarter (monitor changes on disk)• HTTP::Server::PSGI• Debugging middleware• Profiler
    • Testing
    • Testing• Testing your full configuration
    • Testing• Testing your full configuration• Test::WWW::Mechanize::PSGI
    • Testing• Testing your full configuration• Test::WWW::Mechanize::PSGI• Plack::Test
    • Deployment
    • Deployment• No separate configuration files
    • Deployment• No separate configuration files• Easy to choose/change webserver
    • Deployment• No separate configuration files• Easy to choose/change webserver• DotCloud etc - cloud deployment
    • Summary
    • Summary✦ PSGI is an interface, Plack is the code.
    • Summary✦ PSGI is an interface, Plack is the code.✦ Many fast PSGI servers.
    • Summary✦ PSGI is an interface, Plack is the code.✦ Many fast PSGI servers.✦ Adapters and tools for frameworks and webservers.
    • Summary✦ PSGI is an interface, Plack is the code.✦ Many fast PSGI servers.✦ Adapters and tools for frameworks and webservers.✦ An amazing amount of middleware
    • Summary✦ PSGI is an interface, Plack is the code.✦ Many fast PSGI servers.✦ Adapters and tools for frameworks and webservers.✦ An amazing amount of middleware✦ Used in many production systems
    • Use Plack
    • Thank you!Slides: http://slideshare.net/ranguard http://plackperl.org/ irc://irc.perl.org/#plack