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

Like this? Share it with your network

Share

Modern Web Development with Perl

  • 31,416 views
Uploaded on

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.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
31,416
On Slideshare
29,838
From Embeds
1,578
Number of Embeds
21

Actions

Shares
Downloads
224
Comments
0
Likes
6

Embeds 1,578

http://perlhacks.com 1,489
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

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

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
  • 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
  • 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
  • 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
  • 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
  • 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?