Modern Web Development with Perl
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Modern Web Development with Perl

on

  • 29,615 views

An introduction to PSGI and Plack that I gave at the London Perl Workshop in December 2010.

An introduction to PSGI and Plack that I gave at the London Perl Workshop in December 2010.

Statistics

Views

Total Views
29,615
Views on SlideShare
28,047
Embed Views
1,568

Actions

Likes
6
Downloads
222
Comments
0

21 Embeds 1,568

http://perlhacks.com 1479
http://angelreyes.me 19
http://angelreyes.posterous.com 18
http://notasinsentido.tumblr.com 15
http://dave.org.uk 8
http://perlsphere.net 5
http://unjobs.org 4
http://localhost 3
http://sayperl.org 3
http://webcache.googleusercontent.com 2
http://agreyes.blogspot.com 2
http://translate.googleusercontent.com 1
https://duckduckgo.com 1
http://agreyes.blogspot.mx 1
http://127.0.0.1:8795 1
http://www.netvibes.com 1
http://users.unjobs.org 1
http://blekko.com 1
http://www.sayperl.org 1
http://static.slidesharecdn.com 1
http://davorg.theplanetarium.org 1
More...

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike 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

Modern Web Development with Perl Presentation Transcript

  • 1. Modern Perl Web Developement Dave Cross Magnum Solutions Ltd [email_address]
  • 2. Web Development
    • People have been developing web applications for over 15 years
    • 3. Surely it is easy now
    • 4. Lessons have been learned
    • 5. Best practices have been worked out
  • 6. History of Perl & Web
    • Common Gateway Interface 1993
    • 7. Defined the interaction between a web server and a program
    • 8. Dynamic web pages
  • 9. CGI
    • Request includes parameters
    • 10. Program processes parameters and produces response
    • 11. Response includes program's output
  • 12. Mid-Late 1990s
    • Every web site gained dynamic pages
    • 13. Form to email
    • 14. Guestbook
    • 15. Hit counter
    • 16. Etc...
    • 17. Most of them were written in Perl
  • 18. CGI Problems
    • CGI can be slow
    • 19. Perl compiler starts up on every request
    • 20. Can be very slow
    • 21. Not useful for heavy traffic sites
  • 22. mod_perl
    • Everyone used Apache
    • 23. Apache allowed loadable modules
    • 24. mod_perl loads a Perl compiler
    • 25. Persistent Perl processes
    • 26. No more start-up costs
    • 27. Huge performance improvements
  • 28. Downsides
    • Can't just use your CGI programs
      • ModPerl::Registry
    • Program is now called as a subroutine
    • 29. Global variable issues
    • 30. Many programs needed rewrites
    • 31. Different input and output methods
  • 32. Other Environments
    • FastCGI
    • 33. Microsoft IIS
    • 34. lighttpd
    • 35. Etc...
    • 36. Lack of portability
    • 37. Hold that thought
  • 38. CGI Programs
    • CGI programs do three things
    • 39. Read user input
    • 40. Process data
    • 41. Produce output
    • 42. Let's look at input and output in more detail
  • 43. Output
    • CGI programs produce two types of output
    • 44. Headers
      • Content-type
    • Body
      • The actual data (HTML, etc)
  • 45. Simple CGI Output
    • #!/usr/bin/perl print “Content-type: text/plainnn”; print 'The time is: ', scalar localtime;
  • 46. HTML
    • #!/usr/bin/perl print “Content-type: text/htmlnn”; my $time = localtime; print <<END_HTML; <html><head><title>Time</title></head> <body><h1>Time</h1> <p>The time is: $time.</p></body></html> END_HTML
  • 47. Enter CGI.pm
    • CGI.pm standard part of Perl distribution
    • 48. Handles CGI processing for you
    • 49. Input and output
    • 50. Output in the form of CGI & HTML helper functions
  • 51. HTML With CGI.pm
    • #!/usr/bin/perl use CGI ':standard'; print header; # default text/html my $time = localtime; print start_html(title => 'Time'), h1('Time'), p(“The time is: $time”); end_html;
  • 52. Downsides
    • Mixing HTML and Perl code is nasty
    • 53. What if you have a designer?
    • 54. HTML experts don't always know Perl
    • 55. Use a templating system instead
  • 56. Template Toolkit
    • <html> <head> <title>Time</title> </head> <body> <h1>Time</h1> <p>The time is: [% time %].</p> </body> </html>
  • 57. Template Toolkit
    • <html> <head> <title>Time</title> </head> <body> <h1>Time</h1> <p>The time is: [% time %] .</p> </body> </html>
  • 58. Template Toolkit
    • Separate the HTML into a separate file
    • 59. Use tags where the variable output goes
    • 60. Easier to edit by your HTML team
  • 61. Template Toolkit & Perl
    • #!/usr/bin/perl use Template; use CGI 'header'; print header; my $tt = Template->new; my $time = localtime; $tt->process('time.tt', { time => $time } or die $tt->error;
  • 62. User Input
    • Users send input to CGI programs
    • 63. Parameters encoded in the URL
    • 64. http://example.com/cgi-bin/stuff?name=davorg&lang=Perl
    • 65. Need to access these parameters
    • 66. N.B. I'm deliberately ignoring POST requests for simplicity
  • 67. Old Style
    • @pairs = split /&/, $ENV{QUERY_STRING}; foreach $pair (@pairs) { ($k, $v) = split /=/, $pair; $k =~ tr/+/ /; $k =~ s/%([a-f0-9]{2})/pack 'C', hex($1)/ieg; $v =~ tr/+/ /; $v =~ s/%([a-f0-9]{2})/pack 'C', hex($1)/ieg; $form{$k} = $v; } # And then later... my $name = $form{name};
    • @pairs = split /&/, $ENV{QUERY_STRING}; foreach $pair (@pairs) { ($k, $v) = split /=/, $pair;
  • 68. CGI.pm Style
    • use CGI ':standard'; my $name = param('name');
  • 69. However
    • mod_perl has a different method for accessing parameters
    • 70. Apache2::Request
    • 71. Other environments have different methods
    • 72. This is where PSGI comes in
  • 73. PSGI & Plack
  • 74. PSGI/Plack
    • “ PSGI is an interface between Perl web applications and web servers, and Plack is a Perl module and toolkit that contains PSGI middleware, helpers and adapters to web servers.”
      • http://plackperl.org/
  • 75. PSGI/Plack
    • PSGI is a specification (based on Python's WSGI)
    • 76. Plack is a reference implementation (based on Ruby's Rack)
  • 77. The Problem
    • There are many ways to write web applications
    • 78. There are many ways to write web applications in Perl
    • 79. Each is subtly different
    • 80. Hard to move an application between server architectures
  • 81. Server Architectures
    • CGI
    • 82. FastCGI
    • 83. mod_perl
    • 84. etc...
  • 85. Frameworks
    • There are many Perl web application frameworks
    • 86. Each creates applications in subtly different ways
    • 87. Hard to port applications between them
  • 88. The Goal
    • What if we had a specification that allowed us to easily move web applications between server architectures and frameworks
    • 89. PSGI is that specification
  • 90. PSGI Application
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 91. PSGI Application
    • A code reference
    • 92. Passed a reference to an environment hash
    • 93. Returns a reference to a three-element array
      • Status code
      • 94. Headers
      • 95. Body
  • 96. A Code Reference
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 97. A Code Reference
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 98. Environment Hash
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 99. Environment Hash
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 100. Return Array Ref
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 101. Return Array Ref
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 102. Return Array Ref
    • my $app = sub { my $env = shift; return [ 200 , [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 103. Return Array Ref
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ] , [ ‘Hello World’ ], ]; };
  • 104. Return Array Ref
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ] , ]; };
  • 105. Running PSGI App
    • Put code in app.psgi
    • 106. Drop in into a configured PSGI-aware web server
    • 107. Browse to URL
  • 108. PSGI-Aware Server
    • Plack contains a simple test server called plackup
    • 109. $ plackup app.psgi HTTP::Server::PSGI: Accepting connections at http://localhost:5000/
  • 110. More About $env
    • use Data::Dumper; my $app = sub { my $env = shift; return [ 200, [ 'Content-type', 'text/plain' ], [ Dumper $env ], ]; }
  • 111. Plack::Request
    • Plack::Request turns the environment into a request object
  • 112. Plack::Request
    • use Plack::Request; use Data::Dumper; my $app = sub { my $req = Plack::Request->new(shift); return [ 200, [ 'Content-type', 'text/plain' ], [ Dumper $req ], ]; }
  • 113. Plack::Response
    • Plack::Response builds a PSGI response object
  • 114. Plack::Response
    • use Plack::Request; use Plack::Response; use Data::Dumper; my $app = sub { my $req = Plack::Request->new(shift); my $res = Plack::Response->new(200); $res->content_type('text/plain'); $res->body(Dumper $req); return $res->finalize; }
  • 115. Time Example
    • my $app = sub { my $env = shift; return [ 200, [ 'Content-type', 'text/plain' ], [ scalar localtime ], ] };
  • 116. Time With HTML
    • my $app = sub { my $env = shift; my $now = localtime; return [ 200, [ 'Content-type', 'text/html' ], [&quot;<html><head><title>Time</title></head> <body><h1>Time</h1><p>The time is $now</p> </body></html>&quot; ] ] };
  • 117. Time With TT
    • use Template; my $app = sub { my $tt = Template->new; my $out; $tt->process('time.tt', { time => scalar localtime }, $out) or die $tt->error; return [ 200, [ 'Content-type', 'text/html' ], [ $out ] ] };
  • 118. User Input
    • Get user input from two places
    • 119. Parse the query string from the $env hash
    • 120. Ask the Plack::Request object
  • 121. Input
    • use Plack::Request; use Data::Dumper; my $app = sub { my $req = Plack::Request->new(shift); my $content; if (keys %{$req->parameters}) { $content = response($req); } else { $content = form(); } return [ 200, [ 'Content-type', 'text/html' ], [ $content ], ]; };
  • 122. Displaying a Form
    • sub form { return <<END_OF_FORM; <html> ... stuff... <form> <input name=”name”> ... stuff ... </form> </html> END_OF_HTML }
  • 123. Displaying the Response
    • sub response { my $req = shift; my $name = $req->parameters->{name}; print <<END_OF_HTML <html> ... stuff ... <p>Name: $name</p> ... stuff ... </html> END_OF_HTML }
  • 124. Using Templates
    • Both form and response can be produced using TT
    • 125. This is left as an exercise for the reader
  • 126. Building Applications
    • A PSGI program can be an entire application
    • 127. The secret is in the 'path_info' input
    • 128. $env->{PATH_INFO}
    • 129. /
    • 130. /person/1
    • 131. /person/1/delete
  • 132. Building Applications
    • my $app = sub { my $env = shift; my $response = get_response_for( $env->{PATH_INFO} ); return $response; }
  • 133. Frameworks
    • At this point you should probably look at a framework
    • 134. Catalyst
    • 135. Dancer
    • 136. Mojolicious
    • 137. etc...
  • 138. Advanced Plack
  • 139. Middleware
    • Middleware wraps around an application
    • 140. Returns another PSGI application
    • 141. Simple spec makes this easy
    • 142. Plack::Middleware::*
    • 143. Plack::Builder adds middleware configuration language
  • 144. Middleware Example
    • use Plack::Builder; use Plack::Middleware::Runtime; my $app = sub { my $env = shift; return [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world' ], ] }; builder { enable 'Runtime'; $app; }
  • 145. Middleware Example
    • $ HEAD http://localhost:5000 200 OK Date: Tue, 20 Jul 2010 20:25:52 GMT Server: HTTP::Server::PSGI Content-Length: 11 Content-Type: text/plain Client-Date: Tue, 20 Jul 2010 20:25:52 GMT Client-Peer: 127.0.0.1:5000 Client-Response-Num: 1 X-Runtime: 0.000050
  • 146. Middleware Example
    • $ HEAD http://localhost:5000 200 OK Date: Tue, 20 Jul 2010 20:25:52 GMT Server: HTTP::Server::PSGI Content-Length: 11 Content-Type: text/plain Client-Date: Tue, 20 Jul 2010 20:25:52 GMT Client-Peer: 127.0.0.1:5000 Client-Response-Num: 1 X-Runtime: 0.000050
  • 147. Plack::App::*
    • Ready-made solutions for common situations
    • 148. Plack::App::CGIBin
      • Cgi-bin replacement
    • Plack::App::Directory
      • Serve files with directory index
    • Plack::App::URLMap
      • Map apps to different paths
  • 149. Plack::App::*
    • Many more bundled with Plack
    • 150. Configured using Plack::Builder
  • 151. Plack::App::CGIBin
    • use Plack::App::CGIBin; use Plack::Builder; my $app = Plack::App::CGIBin->new( root => '/var/www/cgi-bin' )->to_app; builder { mount '/cgi-bin' => $app; };
  • 152. Plack::App::Directory
    • use Plack::App::Directory; my $app = Plack::App::Directory->new( root => '/home/dave/Dropbox/psgi' )->to_app;
  • 153. Framework Support
    • Many modern Perl applications already support PSGI
    • 154. Catalyst, CGI::Application, Dancer, Jifty, Mason, Maypole, Mojolicious, Squatting, Web::Simple
    • 155. Many more
  • 156. Catalyst Support
    • Catalyst::Engine::PSGI
    • 157. use MyApp; MyApp->setup_engine('PSGI'); my $app = sub { MyApp->run(@_) };
    • 158. Also Catalyst::Helper::PSGI
    • 159. script/myapp_create.pl PSGI
  • 160. PSGI Server Support
    • Many new web servers support PSGI
    • 161. Starman, Starlet, Twiggy, Corona, HTTP::Server::Simple::PSGI
    • 162. Perlbal::Plugin::PSGI
  • 163. PSGI Server Support
    • nginx support
    • 164. mod_psgi
    • 165. Plack::Handler::Apache2
  • 166. Plack::Handler::Apache2
    • <Location /psgi> SetHandler perl-script PerlResponseHandler Plack::Handler::Apache2 PerlSetVar psgi_app /path/to/app.psgi </Location>
  • 167. PSGI/Plack Summary
    • PSGI is a specification
    • 168. Plack is an implementation
    • 169. PSGI makes your life easier
    • 170. Most of the frameworks and server you use already support PSGI
    • 171. No excuse not to use it
  • 172. Further Information
    • perldoc PSGI
    • 173. perldoc Plack
    • 174. http://plackperl.org/
    • 175. http://blog.plackperl.org/
    • 176. http://github.com/miyagawa/Plack
    • 177. #plack on irc.perl.org
  • 178. That's all folks
    • Any questions?