SlideShare ist ein Scribd-Unternehmen logo
1 von 112
Downloaden Sie, um offline zu lesen
London Perl Workshop
12th December 2015
Modern Perl
Web Development
Dave Cross
Magnum Solutions Ltd
dave@mag-sol.com
London Perl Workshop
12th December 2015
Web Development
• People have been developing web
applications for over 20 years
• Surely it is easy now
• Lessons have been learned
• Best practices have been worked out
London Perl Workshop
12th December 2015
History of Perl & Web
• Common Gateway Interface 1993
• Defined the interaction between a web server
and a program
• Dynamic web pages
London Perl Workshop
12th December 2015
CGI
• Request includes parameters
• Program processes parameters and produces
response
• Response includes program's output
London Perl Workshop
12th December 2015
Mid-Late 1990s
• Every web site gained dynamic pages
• Form to email
• Guestbook
• Hit counter
• Etc...
• Most of them were written in Perl
London Perl Workshop
12th December 2015
CGI Problems
• CGI can be slow
• Perl compiler starts up on every request
• Can be very slow
• Not useful for heavy traffic sites
London Perl Workshop
12th December 2015
mod_perl
• Everyone used Apache
• Apache allowed loadable modules
• mod_perl loads a Perl compiler
• Persistent Perl processes
• No more start-up costs
• Huge performance improvements
London Perl Workshop
12th December 2015
Downsides
• Can't just use your CGI programs
– ModPerl::Registry
• Program is now called as a subroutine
• Global variable issues
• Many programs needed rewrites
• Different input and output methods
London Perl Workshop
12th December 2015
Other Environments
• FastCGI
• Microsoft IIS
• nginx
• Etc...
• Lack of portability
• Hold that thought
London Perl Workshop
12th December 2015
CGI Programs
• CGI programs do three things
• Read user input
• Process data
• Produce output
• Let's look at input and output in more detail
London Perl Workshop
12th December 2015
Output
• CGI programs produce two types of output
• Headers
– Content-type
• Body
– The actual data (HTML, etc)
London Perl Workshop
12th December 2015
Simple CGI Output
• #!/usr/bin/perl
print “Content-type: text/plainnn”;
print 'The time is: ',
scalar localtime;
London Perl Workshop
12th December 2015
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
London Perl Workshop
12th December 2015
Enter CGI.pm
• CGI.pm standard part of Perl distribution
• Handles CGI processing for you
• Input and output
• Output in the form of CGI & HTML helper
functions
– HTML helper functions now deprecated
London Perl Workshop
12th December 2015
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;
London Perl Workshop
12th December 2015
Downsides
• Mixing HTML and Perl code is nasty
• What if you have a designer?
• HTML experts don't always know Perl
• Use a templating system instead
London Perl Workshop
12th December 2015
Template Toolkit
• <html>
<head>
<title>Time</title>
</head>
<body>
<h1>Time</h1>
<p>The time is: [% time %].</p>
</body>
</html>
London Perl Workshop
12th December 2015
Template Toolkit
• <html>
<head>
<title>Time</title>
</head>
<body>
<h1>Time</h1>
<p>The time is: [% time %].</p>
</body>
</html>
London Perl Workshop
12th December 2015
Template Toolkit
• Separate the HTML into a separate file
• Use tags where the variable output goes
• Easier to edit by your HTML team
London Perl Workshop
12th December 2015
Template Toolkit & CGI
• #!/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;
London Perl Workshop
12th December 2015
User Input
• Users send input to CGI programs
• Parameters encoded in the URL
• http://example.com/cgi-bin/stuff?
name=davorg&lang=Perl
• Need to access these parameters
• N.B. I'm deliberately ignoring POST requests
for simplicity
London Perl Workshop
12th December 2015
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};
London Perl Workshop
12th December 2015
CGI.pm Style
• use CGI ':standard';
my $name = param('name');
London Perl Workshop
12th December 2015
However
• mod_perl has a different method for
accessing parameters
• Apache2::Request
• Other environments have different methods
• This is where PSGI comes in
London Perl Workshop
12th December 2015
PSGI & Plack
London Perl Workshop
12th December 2015
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/
London Perl Workshop
12th December 2015
PSGI/Plack
• PSGI is a specification (based on Python's
WSGI)
• Plack is a reference implementation and
toolbox (based on Ruby's Rack)
London Perl Workshop
12th December 2015
The Problem
• There are many ways to write web
applications
• There are many ways to write web
applications in Perl
• Each is subtly different
• Hard to move an application between server
architectures
London Perl Workshop
12th December 2015
Server Architectures
• CGI
• FastCGI
• mod_perl
• etc...
London Perl Workshop
12th December 2015
Frameworks
• There are many Perl web application
frameworks
• Each creates applications in subtly different
ways
• Hard to port applications between them
London Perl Workshop
12th December 2015
The Goal
• What if we had a specification that allowed
us to easily move web applications between
server architectures and frameworks
• PSGI is that specification
London Perl Workshop
12th December 2015
Separation
• We know the advantages of separating
processing from display
• PSGI separates processing from deployment
London Perl Workshop
12th December 2015
PSGI Application
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
PSGI Application
• A code reference
• Passed a reference to an environment hash
• Returns a reference to a three-element array
– Status code
– Headers
– Body
London Perl Workshop
12th December 2015
A Code Reference
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
A Code Reference
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Environment Hash
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Environment Hash
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Return Array Ref
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Return Array Ref
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Return Array Ref
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Return Array Ref
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Return Array Ref
• my $app = sub {
my $env = shift;
return [
200,
[ ‘Content-Type’, ‘text/plain’ ],
[ ‘Hello World’ ],
];
};
London Perl Workshop
12th December 2015
Running PSGI App
• Put code in app.psgi
• Drop in into a configured PSGI-aware web
server
• Browse to URL
London Perl Workshop
12th December 2015
PSGI-Aware Server
• Plack contains a simple test server called
plackup
• $ plackup app.psgi
HTTP::Server::PSGI: Accepting connections at
http://localhost:5000/
London Perl Workshop
12th December 2015
More About $env
• use Data::Dumper;
my $app = sub {
my $env = shift;
return [
200,
[ 'Content-type', 'text/plain' ],
[ Dumper $env ],
];
}
London Perl Workshop
12th December 2015
More About $env
• $VAR1 = {
'psgi.streaming' => 1,
'psgi.multithread' => '',
'HTTP_UPGRADE_INSECURE_REQUESTS' => '1',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'psgi.errors' => *::STDERR,
'PATH_INFO' => '/',
'HTTP_ACCEPT_LANGUAGE' => 'en-GB,en-US;q=0.8,en;q=0.6',
'psgi.multiprocess' => '',
'SERVER_NAME' => 0,
'psgi.version' => [ 1, 1 ],
'psgix.input.buffered' => 1,
'psgi.input' => *{'HTTP::Server::PSGI::$input'},
'psgi.url_scheme' => 'http',
'REQUEST_URI' => '/',
'REMOTE_PORT' => 59948,
'HTTP_ACCEPT' =>
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'REQUEST_METHOD' => 'GET',
'psgix.io' => bless( *Symbol::GEN1,
'IO::Socket::INET' ),
'psgi.run_once' => '',
'SCRIPT_NAME' => '',
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate, sdch',
'SERVER_PORT' => 5000,
'HTTP_HOST' => 'localhost:5000',
London Perl Workshop
12th December 2015
Plack::Request
• Plack::Request turns the environment into a
request object
London Perl Workshop
12th December 2015
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 ],
];
}
London Perl Workshop
12th December 2015
Plack::Request
• $VAR1 = bless( {
'env' => {
'SCRIPT_NAME' => '',
'psgi.nonblocking' => '',
'psgi.errors' => *::STDERR,
'SERVER_PROTOCOL' => 'HTTP/1.1',
'HTTP_USER_AGENT' =>
'Wget/1.16.3 (linux-gnu)',
'psgi.url_scheme' => 'http',
'REMOTE_PORT' => 57218,
'SERVER_PORT' => 5000,
'REQUEST_METHOD' => 'GET',
'REQUEST_URI' => '/',
'psgi.version' => [ 1, 1 ],
'psgix.io' =>
bless( *Symbol::GEN1, 'IO::Socket::INET' ),
London Perl Workshop
12th December 2015
Plack::Request
• 'HTTP_ACCEPT_ENCODING' => 'identity',
'psgix.input.buffered' => 1,
'psgi.run_once' => '',
'psgi.streaming' => 1,
'HTTP_ACCEPT' => '*/*',
'HTTP_CONNECTION' => 'Keep-Alive',
'psgi.input' =>
*{'HTTP::Server::PSGI::$input'},
'psgi.multiprocess' => '',
'psgi.multithread' => '',
'QUERY_STRING' => '',
'HTTP_HOST' => 'localhost:5000',
'psgix.harakiri' => 1,
'PATH_INFO' => '/',
'SERVER_NAME' => 0
}
}, 'Plack::Request' );
London Perl Workshop
12th December 2015
Plack::Response
• Plack::Response builds a PSGI response
object
London Perl Workshop
12th December 2015
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;
}
London Perl Workshop
12th December 2015
Time Example
• my $app = sub {
my $env = shift;
my $res = Plack::Response->new(200);
$res->content_type('text/plain');
$res->body(scalar localtime);
return $res->finalize;
};
London Perl Workshop
12th December 2015
Time With HTML
• my $app = sub {
my $env = shift;
my $now = localtime;
my $res = Plack::Response->new(200);
$res->content_type('text/html');
$res->body(
"<html>
<head><title>Time</title></head>
<body><h1>Time</h1><p>The time is $now</p>
</body>
</html>"
);
return $res→finalize;
};
London Perl Workshop
12th December 2015
Time With TT
• use Template;
my $app = sub {
my $tt = Template->new;
my $out;
my $res = Plack::Response->new(200);
$res→content_type('text/html');
$tt->process('time.tt',
{ time => scalar localtime },
$out) or die $tt->error;
$res->body($out);
return $res->finalize;
};
London Perl Workshop
12th December 2015
User Input
• Get user input from two places
• Parse the query string from the $env hash
• Ask the Plack::Request object
London Perl Workshop
12th December 2015
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 ], ];
};
London Perl Workshop
12th December 2015
Displaying a Form
• sub form {
return <<END_OF_FORM;
<html>
... stuff...
<form>
<input name=”name”>
... stuff ...
</form>
</html>
END_OF_HTML
}
London Perl Workshop
12th December 2015
Displaying the Response
• sub response {
my $req = shift;
my $name = $req->parameters->{name};
return <<END_OF_HTML
<html>
... stuff ...
<p>Name: $name</p>
... stuff ...
</html>
END_OF_HTML
}
London Perl Workshop
12th December 2015
Using Templates
• Both form and response can be produced
using TT
• This is left as an exercise for the reader
London Perl Workshop
12th December 2015
Building Applications
• A PSGI program can be an entire application
• The secret is in the 'path_info' input
• $env->{PATH_INFO}
• /
• /person/1
• /person/1/delete
London Perl Workshop
12th December 2015
Building Applications
• my $app = sub {
my $env = shift;
my $req = Plack::Request->new($env);
my $response = get_response_for(
$req->path_info;
);
return $response;
}
London Perl Workshop
12th December 2015
Building Applications
• use Some::Web::App;
my $webapp = Some::Web::App->new;
my $app = sub {
my $env = shift
my $resp = $webapp->get_response_for(
$req->path_info($env);
);
return $response;
}
London Perl Workshop
12th December 2015
Building Applications
• Use Some::Web::App;
return Some::Web::App->to_app;
London Perl Workshop
12th December 2015
Frameworks
• At this point you should probably look at a
framework
• Catalyst
• Dancer2
• Mojolicious
• etc...
London Perl Workshop
12th December 2015
Dancer2 Example
• Use dancer2 to create skeleton app
• dancer2 gen -a MyWebApp
• Creates many files
• MyWebApp/bin/app.psgi
London Perl Workshop
12th December 2015
Dancer2 app.psgi
• #!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyApp;
MyApp->to_app;
London Perl Workshop
12th December 2015
Advertisement
• This is a cut-down version of another course
• Two days in February 2016
• Insert many hours of framework-specific
examples here
• See http://mgnm.at/trn2015
London Perl Workshop
12th December 2015
Plack
Middleware
London Perl Workshop
12th December 2015
Middleware
• Middleware wraps around an application
• Returns another PSGI application
• Simple spec makes this easy
• Plack::Middleware::*
• Plack::Builder adds middleware
configuration language
London Perl Workshop
12th December 2015
Middleware
• package Plack::Middleware::Foo;
use parent qw( Plack::Middleware );
sub call {
my($self, $env) = @_;
# Do something with $env
# $self->app is the original app
my $res = $self->app->($env);
# Do something with $res
return $res;
}
London Perl Workshop
12th December 2015
Middleware Example
• package Plack::Middleware::Runtime;
use strict;
use parent qw(Plack::Middleware);
use Plack::Util;
use Plack::Util::Accessor qw(header_name);
use Time::HiRes;
sub call {
my($self, $env) = @_;
my $start = [ Time::HiRes::gettimeofday ];
my $res = $self->app->($env);
my $header = $self->header_name || 'X-Runtime';
$self->response_cb($res, sub {
my $res = shift;
my $req_time = sprintf '%.6f',
Time::HiRes::tv_interval($start);
Plack::Util::header_set($res->[1], $header, $req_time);
});
}
London Perl Workshop
12th December 2015
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;
}
London Perl Workshop
12th December 2015
Middleware Example
• $ HEAD http://localhost:5000
200 OK
Date: Sun, 06 Dec 2015 14:15:11 GMT
Server: HTTP::Server::PSGI
Content-Length: 11
Content-Type: text/plain
Client-Date: Sun, 06 Dec 2015 14:15:11 GMT
Client-Peer: 127.0.0.1:5000
Client-Response-Num: 1
X-Runtime: 0.000082
London Perl Workshop
12th December 2015
Middleware Example
• $ HEAD http://localhost:5000
200 OK
Date: Sun, 06 Dec 2015 14:15:11 GMT
Server: HTTP::Server::PSGI
Content-Length: 11
Content-Type: text/plain
Client-Date: Sun, 06 Dec 2015 14:15:11 GMT
Client-Peer: 127.0.0.1:5000
Client-Response-Num: 1
X-Runtime: 0.000082
London Perl Workshop
12th December 2015
Middleware Examples
• Many more examples included with Plack
• Plack::Middleware::AccessLog
• Plack::Middleware::ErrorDocument
• Plack::Middleware::Auth::Basic
• Plack::Middleware::Static
• Etc...
London Perl Workshop
12th December 2015
Plack::Middlware::Static
• Bypass app for static files
• use Plack::Builder;
builder {
enable "Plack::Middleware::Static",
path => qr{^/(images|js|css)/},
root => './htdocs/';
$app;
};
London Perl Workshop
12th December 2015
Plack Apps
London Perl Workshop
12th December 2015
Plack::App::*
• Ready-made solutions for common situations
• Plack::App::CGIBin
– Cgi-bin replacement
• Plack::App::Directory
– Serve files with directory index
• Plack::App::URLMap
– Map apps to different paths
London Perl Workshop
12th December 2015
Plack::App::*
• Many more bundled with Plack
• Configured using Plack::Builder
London Perl Workshop
12th December 2015
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;
};
London Perl Workshop
12th December 2015
Plack::App::Directory
• use Plack::App::Directory;
my $app = Plack::App::Directory->new(
root => '/home/dave/Dropbox/psgi'
)->to_app;
London Perl Workshop
12th December 2015
Debugging
PSGI Apps
London Perl Workshop
12th December 2015
Debugging Web Apps
• Debugging web apps is difficult
• Hard to trace execution
• Log messages
London Perl Workshop
12th December 2015
Plack::Middleware::Debug
• Adds a very useful debug panel to your
application
• #!/usr/bin/env perl
use strict
use warnings;
use Plack::Builder;
use Literature; # Dancer app
my $app = Literature->to_app;
builder {
enable 'Debug';
$app;
}
London Perl Workshop
12th December 2015
Plack::Middleware::Debu
g
London Perl Workshop
12th December 2015
Plack::Middleware::Debu
g
London Perl Workshop
12th December 2015
Plack::Middleware::Debu
g
London Perl Workshop
12th December 2015
Plack::Middleware::Debu
g
London Perl Workshop
12th December 2015
Plack::Middleware::Debu
g
London Perl Workshop
12th December 2015
Plack::Middleware::Debu
g
London Perl Workshop
12th December 2015
Plack::Debugger
• Plack::Debugger is a replacement for
Plack::Middleware::Debug
• Harder to configure
• More flexible
• Work in progress
• Worth watching
London Perl Workshop
12th December 2015
Testing
PSGI Apps
London Perl Workshop
12th December 2015
Testing Web Apps
• Testing web apps is hard
• For the same reasons as debugging
• WWW::Mechanize
• Selenium
London Perl Workshop
12th December 2015
Plack::Test
• The simple Plack specification makes it easy
to write a testing layer
• Plack::Test
• Standard for all PSGI apps
• Dancer2::Test (for example) is now
deprecated
London Perl Workshop
12th December 2015
Using Plack::Test
• Three modes of use
• Examples all require the following
• use Plack::Test;
use HTTP::Request::Common;
London Perl Workshop
12th December 2015
Positional Params
• my $app = sub {
return [ 200, [], [ "Hello "] ]
};
my $client = sub {
my $cb = shift;
my $res = $cb->(GET "/");
is $res->content, "Hello";
};
test_psgi $app, $client;
London Perl Workshop
12th December 2015
Named Params
• my $app = sub {
return [ 200, [], [ "Hello "] ]
};
my $client = sub {
my $cb = shift;
my $res = $cb->("GET /");
is $res->content, “Hello”;
}
test_psgi app => $app,
client => $client;
London Perl Workshop
12th December 2015
Object Oriented
• my $app = sub {
return [ 200, [], [ "Hello "] ]
};
my $test = Plack::Test->create($app);
my $res = $test->request(GET "/");
is $res->content, "Hello";
London Perl Workshop
12th December 2015
Deploying
PSGI Apps
London Perl Workshop
12th December 2015
Deploying PSGI Apps
• PSGI separates implementation from
deployment
• This is a major advantage
• Concentrate on the right problems at the right
time
• Easily switch between deployment
environments
London Perl Workshop
12th December 2015
PSGI Server Support
• Many new web servers support PSGI
• Starman, Starlet, Twiggy, Corona,
HTTP::Server::Simple::PSGI
• Perlbal::Plugin::PSGI
London Perl Workshop
12th December 2015
PSGI Server Support
• nginx support
• mod_psgi
• Plack::Handler::Apache2
London Perl Workshop
12th December 2015
Plack::Handler::Apache2
• <Location /psgi>
SetHandler perl-script
PerlResponseHandler Plack::Handler::Apache2
PerlSetVar psgi_app /path/to/app.psgi
</Location>
London Perl Workshop
12th December 2015
Deploy Under nginx
• Use plackup to start the app
• plackup -S Starman app.psgi
– Starman is a high-performance preforking
PSGI/Plack web server
• Configure nginx to proxy requests to port
5000
London Perl Workshop
12th December 2015
Advertisement
• Deployment will be covered in far more
detail on the extended course
• We will have practical sessions trying out
various deployment scenarios
• We will turn our app into a real service
• See http://mgnm.at/trn2015
London Perl Workshop
12th December 2015
Summary
London Perl Workshop
12th December 2015
CGI Summary
• CGI is dead
– Or, at least, it should be
• Don't use CGI for new development
• If you must maintain CGI code see
CGI::Alternatives
• Switch to PSGI
London Perl Workshop
12th December 2015
PSGI/Plack Summary
• PSGI is a specification
• Plack is an implementation/toolbox
• PSGI makes your life easier
• Most of the frameworks and servers you use
already support PSGI
• No excuse not to use it
London Perl Workshop
12th December 2015
Further Information
• perldoc PSGI
• perldoc Plack
• http://plackperl.org/
• http://blog.plackperl.org/
• http://github.com/miyagawa/Plack
• #plack on irc.perl.org
London Perl Workshop
12th December 2015
That's all folks
• Any questions?

Weitere ähnliche Inhalte

Was ist angesagt?

PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
Modern Perl Web Development with Dancer
Modern Perl Web Development with DancerModern Perl Web Development with Dancer
Modern Perl Web Development with DancerDave Cross
 
Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Chris Tankersley
 
A reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webA reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webWallace Reis
 
Killer Docker Workflows for Development
Killer Docker Workflows for DevelopmentKiller Docker Workflows for Development
Killer Docker Workflows for DevelopmentChris Tankersley
 
Modern Perl
Modern PerlModern Perl
Modern PerlDave Cross
 
Deploying Perl apps on dotCloud
Deploying Perl apps on dotCloudDeploying Perl apps on dotCloud
Deploying Perl apps on dotClouddaoswald
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable SoftwareTatsuhiko Miyagawa
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Lisp Meet Up #31, Clake: a GNU make-like build utility in Common Lisp
Lisp Meet Up #31, Clake: a GNU make-like build utility in Common LispLisp Meet Up #31, Clake: a GNU make-like build utility in Common Lisp
Lisp Meet Up #31, Clake: a GNU make-like build utility in Common Lispmasayukitakagi
 
Till Vollmer Presentation
Till Vollmer PresentationTill Vollmer Presentation
Till Vollmer PresentationRubyOnRails_dude
 
Workin On The Rails Road
Workin On The Rails RoadWorkin On The Rails Road
Workin On The Rails RoadRubyOnRails_dude
 
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service ManagerChris Tankersley
 

Was ist angesagt? (20)

PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
Modern Perl Web Development with Dancer
Modern Perl Web Development with DancerModern Perl Web Development with Dancer
Modern Perl Web Development with Dancer
 
Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)
 
A reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webA reviravolta do desenvolvimento web
A reviravolta do desenvolvimento web
 
Killer Docker Workflows for Development
Killer Docker Workflows for DevelopmentKiller Docker Workflows for Development
Killer Docker Workflows for Development
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Deploying Perl apps on dotCloud
Deploying Perl apps on dotCloudDeploying Perl apps on dotCloud
Deploying Perl apps on dotCloud
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
 
Plack at OSCON 2010
Plack at OSCON 2010Plack at OSCON 2010
Plack at OSCON 2010
 
Lisp Meet Up #31, Clake: a GNU make-like build utility in Common Lisp
Lisp Meet Up #31, Clake: a GNU make-like build utility in Common LispLisp Meet Up #31, Clake: a GNU make-like build utility in Common Lisp
Lisp Meet Up #31, Clake: a GNU make-like build utility in Common Lisp
 
Till Vollmer Presentation
Till Vollmer PresentationTill Vollmer Presentation
Till Vollmer Presentation
 
Workin On The Rails Road
Workin On The Rails RoadWorkin On The Rails Road
Workin On The Rails Road
 
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service Manager
 

Andere mochten auch

Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011leo lapworth
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev AssistantDave Cross
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven PublishingDave Cross
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Masahiro Nagano
 
Medium Perl
Medium PerlMedium Perl
Medium PerlDave Cross
 
Mojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tMojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tCosimo Streppone
 
Modern Core Perl
Modern Core PerlModern Core Perl
Modern Core PerlDave Cross
 
CPANci: Continuous Integration for CPAN
CPANci: Continuous Integration for CPANCPANci: Continuous Integration for CPAN
CPANci: Continuous Integration for CPANMike Friedman
 
Writing webapps with Perl Dancer
Writing webapps with Perl DancerWriting webapps with Perl Dancer
Writing webapps with Perl DancerAlexis Sukrieh
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server Masahiro Nagano
 
Error(s) Free Programming
Error(s) Free ProgrammingError(s) Free Programming
Error(s) Free ProgrammingDave Cross
 
Mojolicious. The web in a box!
Mojolicious. The web in a box!Mojolicious. The web in a box!
Mojolicious. The web in a box!Anatoly Sharifulin
 
Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013Arpad Szasz
 
Modern Perl Catch-Up
Modern Perl Catch-UpModern Perl Catch-Up
Modern Perl Catch-UpDave Cross
 
Perl Dancer for Python programmers
Perl Dancer for Python programmersPerl Dancer for Python programmers
Perl Dancer for Python programmersxSawyer
 
Simple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlSimple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlKent Cowgill
 
How CPAN Testers helped me improve my module
How CPAN Testers helped me improve my moduleHow CPAN Testers helped me improve my module
How CPAN Testers helped me improve my moduleacme
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 

Andere mochten auch (19)

Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev Assistant
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven Publishing
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14
 
Medium Perl
Medium PerlMedium Perl
Medium Perl
 
Mojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tMojolicious: what works and what doesn't
Mojolicious: what works and what doesn't
 
Modern Core Perl
Modern Core PerlModern Core Perl
Modern Core Perl
 
CPANci: Continuous Integration for CPAN
CPANci: Continuous Integration for CPANCPANci: Continuous Integration for CPAN
CPANci: Continuous Integration for CPAN
 
Writing webapps with Perl Dancer
Writing webapps with Perl DancerWriting webapps with Perl Dancer
Writing webapps with Perl Dancer
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
Error(s) Free Programming
Error(s) Free ProgrammingError(s) Free Programming
Error(s) Free Programming
 
Mojolicious. The web in a box!
Mojolicious. The web in a box!Mojolicious. The web in a box!
Mojolicious. The web in a box!
 
Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013Perl hosting for beginners - Cluj.pm March 2013
Perl hosting for beginners - Cluj.pm March 2013
 
Modern Perl Catch-Up
Modern Perl Catch-UpModern Perl Catch-Up
Modern Perl Catch-Up
 
Perl Dancer for Python programmers
Perl Dancer for Python programmersPerl Dancer for Python programmers
Perl Dancer for Python programmers
 
Simple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlSimple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with Perl
 
How CPAN Testers helped me improve my module
How CPAN Testers helped me improve my moduleHow CPAN Testers helped me improve my module
How CPAN Testers helped me improve my module
 
Perl Scripting
Perl ScriptingPerl Scripting
Perl Scripting
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 

Ähnlich wie Modern Web Development with Perl

REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterSachin G Kulkarni
 
Django Introduction & Tutorial
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial之宇 趙
 
Women Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API WorkshopWomen Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API WorkshopEddie Lau
 
PHP as a Service TDC2019
PHP as a Service TDC2019PHP as a Service TDC2019
PHP as a Service TDC2019Paulo Victor Gomes
 
2019 11-bgphp
2019 11-bgphp2019 11-bgphp
2019 11-bgphpdantleech
 
Make your life easy with WP-CLI
Make your life easy with WP-CLIMake your life easy with WP-CLI
Make your life easy with WP-CLIMichael Corkum
 
Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...
Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...
Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...Edward Wilde
 
Getting Started With Aura
Getting Started With AuraGetting Started With Aura
Getting Started With AuraChris Tankersley
 
They why behind php frameworks
They why behind php frameworksThey why behind php frameworks
They why behind php frameworksKirk Madera
 
Ci/CD platform with drone and gogs
Ci/CD platform with drone and gogsCi/CD platform with drone and gogs
Ci/CD platform with drone and gogsPol Jane
 
Website designing company_in_delhi_phpwebdevelopment
Website designing company_in_delhi_phpwebdevelopmentWebsite designing company_in_delhi_phpwebdevelopment
Website designing company_in_delhi_phpwebdevelopmentCss Founder
 
PowerShell Basics for Office Apps and Servers
PowerShell Basics for Office Apps and ServersPowerShell Basics for Office Apps and Servers
PowerShell Basics for Office Apps and ServersGreg McMurray
 
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...CodelyTV
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5Darren Craig
 
Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程jeffz
 
Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!cloudbring
 
Developing SOLID Code
Developing SOLID CodeDeveloping SOLID Code
Developing SOLID CodeMark Niebergall
 

Ähnlich wie Modern Web Development with Perl (20)

REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
 
Modern php
Modern phpModern php
Modern php
 
Django Introduction & Tutorial
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
Women Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API WorkshopWomen Who Code - RSpec JSON API Workshop
Women Who Code - RSpec JSON API Workshop
 
PHP as a Service TDC2019
PHP as a Service TDC2019PHP as a Service TDC2019
PHP as a Service TDC2019
 
2019 11-bgphp
2019 11-bgphp2019 11-bgphp
2019 11-bgphp
 
Make your life easy with WP-CLI
Make your life easy with WP-CLIMake your life easy with WP-CLI
Make your life easy with WP-CLI
 
Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...
Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...
Docker and serverless Randstad Jan 2019: OpenFaaS Serverless: when functions ...
 
Getting Started With Aura
Getting Started With AuraGetting Started With Aura
Getting Started With Aura
 
They why behind php frameworks
They why behind php frameworksThey why behind php frameworks
They why behind php frameworks
 
Ci/CD platform with drone and gogs
Ci/CD platform with drone and gogsCi/CD platform with drone and gogs
Ci/CD platform with drone and gogs
 
Website designing company_in_delhi_phpwebdevelopment
Website designing company_in_delhi_phpwebdevelopmentWebsite designing company_in_delhi_phpwebdevelopment
Website designing company_in_delhi_phpwebdevelopment
 
PowerShell Basics for Office Apps and Servers
PowerShell Basics for Office Apps and ServersPowerShell Basics for Office Apps and Servers
PowerShell Basics for Office Apps and Servers
 
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程Documentation Insight技术架构与开发历程
Documentation Insight技术架构与开发历程
 
Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!
 
Developing SOLID Code
Developing SOLID CodeDeveloping SOLID Code
Developing SOLID Code
 

Mehr von Dave Cross

Measuring the Quality of Your Perl Code
Measuring the Quality of Your Perl CodeMeasuring the Quality of Your Perl Code
Measuring the Quality of Your Perl CodeDave Cross
 
Apollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter BotApollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter BotDave Cross
 
Monoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver BulletsMonoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver BulletsDave Cross
 
The Professional Programmer
The Professional ProgrammerThe Professional Programmer
The Professional ProgrammerDave Cross
 
I'm A Republic (Honest!)
I'm A Republic (Honest!)I'm A Republic (Honest!)
I'm A Republic (Honest!)Dave Cross
 
Web Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your GooglejuiceWeb Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your GooglejuiceDave Cross
 
Freeing Tower Bridge
Freeing Tower BridgeFreeing Tower Bridge
Freeing Tower BridgeDave Cross
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven PublishingDave Cross
 
TwittElection
TwittElectionTwittElection
TwittElectionDave Cross
 
Return to the Kingdom of the Blind
Return to the Kingdom of the BlindReturn to the Kingdom of the Blind
Return to the Kingdom of the BlindDave Cross
 
Github, Travis-CI and Perl
Github, Travis-CI and PerlGithub, Travis-CI and Perl
Github, Travis-CI and PerlDave Cross
 
Object-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and MooseObject-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and MooseDave Cross
 
Database Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::ClassDatabase Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::ClassDave Cross
 
Modern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersModern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersDave Cross
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI ArchiveDave Cross
 
The Kingdom of the Blind
The Kingdom of the BlindThe Kingdom of the Blind
The Kingdom of the BlindDave Cross
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI ArchiveDave Cross
 
Introduction to OO Perl with Moose
Introduction to OO Perl with MooseIntroduction to OO Perl with Moose
Introduction to OO Perl with MooseDave Cross
 
Perl Training
Perl TrainingPerl Training
Perl TrainingDave Cross
 
Perl Masons
Perl MasonsPerl Masons
Perl MasonsDave Cross
 

Mehr von Dave Cross (20)

Measuring the Quality of Your Perl Code
Measuring the Quality of Your Perl CodeMeasuring the Quality of Your Perl Code
Measuring the Quality of Your Perl Code
 
Apollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter BotApollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter Bot
 
Monoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver BulletsMonoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver Bullets
 
The Professional Programmer
The Professional ProgrammerThe Professional Programmer
The Professional Programmer
 
I'm A Republic (Honest!)
I'm A Republic (Honest!)I'm A Republic (Honest!)
I'm A Republic (Honest!)
 
Web Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your GooglejuiceWeb Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your Googlejuice
 
Freeing Tower Bridge
Freeing Tower BridgeFreeing Tower Bridge
Freeing Tower Bridge
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven Publishing
 
TwittElection
TwittElectionTwittElection
TwittElection
 
Return to the Kingdom of the Blind
Return to the Kingdom of the BlindReturn to the Kingdom of the Blind
Return to the Kingdom of the Blind
 
Github, Travis-CI and Perl
Github, Travis-CI and PerlGithub, Travis-CI and Perl
Github, Travis-CI and Perl
 
Object-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and MooseObject-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and Moose
 
Database Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::ClassDatabase Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::Class
 
Modern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersModern Perl for Non-Perl Programmers
Modern Perl for Non-Perl Programmers
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI Archive
 
The Kingdom of the Blind
The Kingdom of the BlindThe Kingdom of the Blind
The Kingdom of the Blind
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI Archive
 
Introduction to OO Perl with Moose
Introduction to OO Perl with MooseIntroduction to OO Perl with Moose
Introduction to OO Perl with Moose
 
Perl Training
Perl TrainingPerl Training
Perl Training
 
Perl Masons
Perl MasonsPerl Masons
Perl Masons
 

KĂźrzlich hochgeladen

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024SynarionITSolutions
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Principled Technologies
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 

KĂźrzlich hochgeladen (20)

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 

Modern Web Development with Perl

  • 1. London Perl Workshop 12th December 2015 Modern Perl Web Development Dave Cross Magnum Solutions Ltd dave@mag-sol.com
  • 2. London Perl Workshop 12th December 2015 Web Development • People have been developing web applications for over 20 years • Surely it is easy now • Lessons have been learned • Best practices have been worked out
  • 3. London Perl Workshop 12th December 2015 History of Perl & Web • Common Gateway Interface 1993 • Defined the interaction between a web server and a program • Dynamic web pages
  • 4. London Perl Workshop 12th December 2015 CGI • Request includes parameters • Program processes parameters and produces response • Response includes program's output
  • 5. London Perl Workshop 12th December 2015 Mid-Late 1990s • Every web site gained dynamic pages • Form to email • Guestbook • Hit counter • Etc... • Most of them were written in Perl
  • 6. London Perl Workshop 12th December 2015 CGI Problems • CGI can be slow • Perl compiler starts up on every request • Can be very slow • Not useful for heavy traffic sites
  • 7. London Perl Workshop 12th December 2015 mod_perl • Everyone used Apache • Apache allowed loadable modules • mod_perl loads a Perl compiler • Persistent Perl processes • No more start-up costs • Huge performance improvements
  • 8. London Perl Workshop 12th December 2015 Downsides • Can't just use your CGI programs – ModPerl::Registry • Program is now called as a subroutine • Global variable issues • Many programs needed rewrites • Different input and output methods
  • 9. London Perl Workshop 12th December 2015 Other Environments • FastCGI • Microsoft IIS • nginx • Etc... • Lack of portability • Hold that thought
  • 10. London Perl Workshop 12th December 2015 CGI Programs • CGI programs do three things • Read user input • Process data • Produce output • Let's look at input and output in more detail
  • 11. London Perl Workshop 12th December 2015 Output • CGI programs produce two types of output • Headers – Content-type • Body – The actual data (HTML, etc)
  • 12. London Perl Workshop 12th December 2015 Simple CGI Output • #!/usr/bin/perl print “Content-type: text/plainnn”; print 'The time is: ', scalar localtime;
  • 13. London Perl Workshop 12th December 2015 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
  • 14. London Perl Workshop 12th December 2015 Enter CGI.pm • CGI.pm standard part of Perl distribution • Handles CGI processing for you • Input and output • Output in the form of CGI & HTML helper functions – HTML helper functions now deprecated
  • 15. London Perl Workshop 12th December 2015 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;
  • 16. London Perl Workshop 12th December 2015 Downsides • Mixing HTML and Perl code is nasty • What if you have a designer? • HTML experts don't always know Perl • Use a templating system instead
  • 17. London Perl Workshop 12th December 2015 Template Toolkit • <html> <head> <title>Time</title> </head> <body> <h1>Time</h1> <p>The time is: [% time %].</p> </body> </html>
  • 18. London Perl Workshop 12th December 2015 Template Toolkit • <html> <head> <title>Time</title> </head> <body> <h1>Time</h1> <p>The time is: [% time %].</p> </body> </html>
  • 19. London Perl Workshop 12th December 2015 Template Toolkit • Separate the HTML into a separate file • Use tags where the variable output goes • Easier to edit by your HTML team
  • 20. London Perl Workshop 12th December 2015 Template Toolkit & CGI • #!/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;
  • 21. London Perl Workshop 12th December 2015 User Input • Users send input to CGI programs • Parameters encoded in the URL • http://example.com/cgi-bin/stuff? name=davorg&lang=Perl • Need to access these parameters • N.B. I'm deliberately ignoring POST requests for simplicity
  • 22. London Perl Workshop 12th December 2015 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};
  • 23. London Perl Workshop 12th December 2015 CGI.pm Style • use CGI ':standard'; my $name = param('name');
  • 24. London Perl Workshop 12th December 2015 However • mod_perl has a different method for accessing parameters • Apache2::Request • Other environments have different methods • This is where PSGI comes in
  • 25. London Perl Workshop 12th December 2015 PSGI & Plack
  • 26. London Perl Workshop 12th December 2015 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/
  • 27. London Perl Workshop 12th December 2015 PSGI/Plack • PSGI is a specification (based on Python's WSGI) • Plack is a reference implementation and toolbox (based on Ruby's Rack)
  • 28. London Perl Workshop 12th December 2015 The Problem • There are many ways to write web applications • There are many ways to write web applications in Perl • Each is subtly different • Hard to move an application between server architectures
  • 29. London Perl Workshop 12th December 2015 Server Architectures • CGI • FastCGI • mod_perl • etc...
  • 30. London Perl Workshop 12th December 2015 Frameworks • There are many Perl web application frameworks • Each creates applications in subtly different ways • Hard to port applications between them
  • 31. London Perl Workshop 12th December 2015 The Goal • What if we had a specification that allowed us to easily move web applications between server architectures and frameworks • PSGI is that specification
  • 32. London Perl Workshop 12th December 2015 Separation • We know the advantages of separating processing from display • PSGI separates processing from deployment
  • 33. London Perl Workshop 12th December 2015 PSGI Application • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 34. London Perl Workshop 12th December 2015 PSGI Application • A code reference • Passed a reference to an environment hash • Returns a reference to a three-element array – Status code – Headers – Body
  • 35. London Perl Workshop 12th December 2015 A Code Reference • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 36. London Perl Workshop 12th December 2015 A Code Reference • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 37. London Perl Workshop 12th December 2015 Environment Hash • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 38. London Perl Workshop 12th December 2015 Environment Hash • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 39. London Perl Workshop 12th December 2015 Return Array Ref • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 40. London Perl Workshop 12th December 2015 Return Array Ref • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 41. London Perl Workshop 12th December 2015 Return Array Ref • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 42. London Perl Workshop 12th December 2015 Return Array Ref • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 43. London Perl Workshop 12th December 2015 Return Array Ref • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 44. London Perl Workshop 12th December 2015 Running PSGI App • Put code in app.psgi • Drop in into a configured PSGI-aware web server • Browse to URL
  • 45. London Perl Workshop 12th December 2015 PSGI-Aware Server • Plack contains a simple test server called plackup • $ plackup app.psgi HTTP::Server::PSGI: Accepting connections at http://localhost:5000/
  • 46. London Perl Workshop 12th December 2015 More About $env • use Data::Dumper; my $app = sub { my $env = shift; return [ 200, [ 'Content-type', 'text/plain' ], [ Dumper $env ], ]; }
  • 47. London Perl Workshop 12th December 2015 More About $env • $VAR1 = { 'psgi.streaming' => 1, 'psgi.multithread' => '', 'HTTP_UPGRADE_INSECURE_REQUESTS' => '1', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'psgi.errors' => *::STDERR, 'PATH_INFO' => '/', 'HTTP_ACCEPT_LANGUAGE' => 'en-GB,en-US;q=0.8,en;q=0.6', 'psgi.multiprocess' => '', 'SERVER_NAME' => 0, 'psgi.version' => [ 1, 1 ], 'psgix.input.buffered' => 1, 'psgi.input' => *{'HTTP::Server::PSGI::$input'}, 'psgi.url_scheme' => 'http', 'REQUEST_URI' => '/', 'REMOTE_PORT' => 59948, 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'REQUEST_METHOD' => 'GET', 'psgix.io' => bless( *Symbol::GEN1, 'IO::Socket::INET' ), 'psgi.run_once' => '', 'SCRIPT_NAME' => '', 'HTTP_ACCEPT_ENCODING' => 'gzip, deflate, sdch', 'SERVER_PORT' => 5000, 'HTTP_HOST' => 'localhost:5000',
  • 48. London Perl Workshop 12th December 2015 Plack::Request • Plack::Request turns the environment into a request object
  • 49. London Perl Workshop 12th December 2015 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 ], ]; }
  • 50. London Perl Workshop 12th December 2015 Plack::Request • $VAR1 = bless( { 'env' => { 'SCRIPT_NAME' => '', 'psgi.nonblocking' => '', 'psgi.errors' => *::STDERR, 'SERVER_PROTOCOL' => 'HTTP/1.1', 'HTTP_USER_AGENT' => 'Wget/1.16.3 (linux-gnu)', 'psgi.url_scheme' => 'http', 'REMOTE_PORT' => 57218, 'SERVER_PORT' => 5000, 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/', 'psgi.version' => [ 1, 1 ], 'psgix.io' => bless( *Symbol::GEN1, 'IO::Socket::INET' ),
  • 51. London Perl Workshop 12th December 2015 Plack::Request • 'HTTP_ACCEPT_ENCODING' => 'identity', 'psgix.input.buffered' => 1, 'psgi.run_once' => '', 'psgi.streaming' => 1, 'HTTP_ACCEPT' => '*/*', 'HTTP_CONNECTION' => 'Keep-Alive', 'psgi.input' => *{'HTTP::Server::PSGI::$input'}, 'psgi.multiprocess' => '', 'psgi.multithread' => '', 'QUERY_STRING' => '', 'HTTP_HOST' => 'localhost:5000', 'psgix.harakiri' => 1, 'PATH_INFO' => '/', 'SERVER_NAME' => 0 } }, 'Plack::Request' );
  • 52. London Perl Workshop 12th December 2015 Plack::Response • Plack::Response builds a PSGI response object
  • 53. London Perl Workshop 12th December 2015 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; }
  • 54. London Perl Workshop 12th December 2015 Time Example • my $app = sub { my $env = shift; my $res = Plack::Response->new(200); $res->content_type('text/plain'); $res->body(scalar localtime); return $res->finalize; };
  • 55. London Perl Workshop 12th December 2015 Time With HTML • my $app = sub { my $env = shift; my $now = localtime; my $res = Plack::Response->new(200); $res->content_type('text/html'); $res->body( "<html> <head><title>Time</title></head> <body><h1>Time</h1><p>The time is $now</p> </body> </html>" ); return $res→finalize; };
  • 56. London Perl Workshop 12th December 2015 Time With TT • use Template; my $app = sub { my $tt = Template->new; my $out; my $res = Plack::Response->new(200); $res→content_type('text/html'); $tt->process('time.tt', { time => scalar localtime }, $out) or die $tt->error; $res->body($out); return $res->finalize; };
  • 57. London Perl Workshop 12th December 2015 User Input • Get user input from two places • Parse the query string from the $env hash • Ask the Plack::Request object
  • 58. London Perl Workshop 12th December 2015 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 ], ]; };
  • 59. London Perl Workshop 12th December 2015 Displaying a Form • sub form { return <<END_OF_FORM; <html> ... stuff... <form> <input name=”name”> ... stuff ... </form> </html> END_OF_HTML }
  • 60. London Perl Workshop 12th December 2015 Displaying the Response • sub response { my $req = shift; my $name = $req->parameters->{name}; return <<END_OF_HTML <html> ... stuff ... <p>Name: $name</p> ... stuff ... </html> END_OF_HTML }
  • 61. London Perl Workshop 12th December 2015 Using Templates • Both form and response can be produced using TT • This is left as an exercise for the reader
  • 62. London Perl Workshop 12th December 2015 Building Applications • A PSGI program can be an entire application • The secret is in the 'path_info' input • $env->{PATH_INFO} • / • /person/1 • /person/1/delete
  • 63. London Perl Workshop 12th December 2015 Building Applications • my $app = sub { my $env = shift; my $req = Plack::Request->new($env); my $response = get_response_for( $req->path_info; ); return $response; }
  • 64. London Perl Workshop 12th December 2015 Building Applications • use Some::Web::App; my $webapp = Some::Web::App->new; my $app = sub { my $env = shift my $resp = $webapp->get_response_for( $req->path_info($env); ); return $response; }
  • 65. London Perl Workshop 12th December 2015 Building Applications • Use Some::Web::App; return Some::Web::App->to_app;
  • 66. London Perl Workshop 12th December 2015 Frameworks • At this point you should probably look at a framework • Catalyst • Dancer2 • Mojolicious • etc...
  • 67. London Perl Workshop 12th December 2015 Dancer2 Example • Use dancer2 to create skeleton app • dancer2 gen -a MyWebApp • Creates many files • MyWebApp/bin/app.psgi
  • 68. London Perl Workshop 12th December 2015 Dancer2 app.psgi • #!/usr/bin/env perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/../lib"; use MyApp; MyApp->to_app;
  • 69. London Perl Workshop 12th December 2015 Advertisement • This is a cut-down version of another course • Two days in February 2016 • Insert many hours of framework-specific examples here • See http://mgnm.at/trn2015
  • 70. London Perl Workshop 12th December 2015 Plack Middleware
  • 71. London Perl Workshop 12th December 2015 Middleware • Middleware wraps around an application • Returns another PSGI application • Simple spec makes this easy • Plack::Middleware::* • Plack::Builder adds middleware configuration language
  • 72. London Perl Workshop 12th December 2015 Middleware • package Plack::Middleware::Foo; use parent qw( Plack::Middleware ); sub call { my($self, $env) = @_; # Do something with $env # $self->app is the original app my $res = $self->app->($env); # Do something with $res return $res; }
  • 73. London Perl Workshop 12th December 2015 Middleware Example • package Plack::Middleware::Runtime; use strict; use parent qw(Plack::Middleware); use Plack::Util; use Plack::Util::Accessor qw(header_name); use Time::HiRes; sub call { my($self, $env) = @_; my $start = [ Time::HiRes::gettimeofday ]; my $res = $self->app->($env); my $header = $self->header_name || 'X-Runtime'; $self->response_cb($res, sub { my $res = shift; my $req_time = sprintf '%.6f', Time::HiRes::tv_interval($start); Plack::Util::header_set($res->[1], $header, $req_time); }); }
  • 74. London Perl Workshop 12th December 2015 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; }
  • 75. London Perl Workshop 12th December 2015 Middleware Example • $ HEAD http://localhost:5000 200 OK Date: Sun, 06 Dec 2015 14:15:11 GMT Server: HTTP::Server::PSGI Content-Length: 11 Content-Type: text/plain Client-Date: Sun, 06 Dec 2015 14:15:11 GMT Client-Peer: 127.0.0.1:5000 Client-Response-Num: 1 X-Runtime: 0.000082
  • 76. London Perl Workshop 12th December 2015 Middleware Example • $ HEAD http://localhost:5000 200 OK Date: Sun, 06 Dec 2015 14:15:11 GMT Server: HTTP::Server::PSGI Content-Length: 11 Content-Type: text/plain Client-Date: Sun, 06 Dec 2015 14:15:11 GMT Client-Peer: 127.0.0.1:5000 Client-Response-Num: 1 X-Runtime: 0.000082
  • 77. London Perl Workshop 12th December 2015 Middleware Examples • Many more examples included with Plack • Plack::Middleware::AccessLog • Plack::Middleware::ErrorDocument • Plack::Middleware::Auth::Basic • Plack::Middleware::Static • Etc...
  • 78. London Perl Workshop 12th December 2015 Plack::Middlware::Static • Bypass app for static files • use Plack::Builder; builder { enable "Plack::Middleware::Static", path => qr{^/(images|js|css)/}, root => './htdocs/'; $app; };
  • 79. London Perl Workshop 12th December 2015 Plack Apps
  • 80. London Perl Workshop 12th December 2015 Plack::App::* • Ready-made solutions for common situations • Plack::App::CGIBin – Cgi-bin replacement • Plack::App::Directory – Serve files with directory index • Plack::App::URLMap – Map apps to different paths
  • 81. London Perl Workshop 12th December 2015 Plack::App::* • Many more bundled with Plack • Configured using Plack::Builder
  • 82. London Perl Workshop 12th December 2015 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; };
  • 83. London Perl Workshop 12th December 2015 Plack::App::Directory • use Plack::App::Directory; my $app = Plack::App::Directory->new( root => '/home/dave/Dropbox/psgi' )->to_app;
  • 84. London Perl Workshop 12th December 2015 Debugging PSGI Apps
  • 85. London Perl Workshop 12th December 2015 Debugging Web Apps • Debugging web apps is difficult • Hard to trace execution • Log messages
  • 86. London Perl Workshop 12th December 2015 Plack::Middleware::Debug • Adds a very useful debug panel to your application • #!/usr/bin/env perl use strict use warnings; use Plack::Builder; use Literature; # Dancer app my $app = Literature->to_app; builder { enable 'Debug'; $app; }
  • 87. London Perl Workshop 12th December 2015 Plack::Middleware::Debu g
  • 88. London Perl Workshop 12th December 2015 Plack::Middleware::Debu g
  • 89. London Perl Workshop 12th December 2015 Plack::Middleware::Debu g
  • 90. London Perl Workshop 12th December 2015 Plack::Middleware::Debu g
  • 91. London Perl Workshop 12th December 2015 Plack::Middleware::Debu g
  • 92. London Perl Workshop 12th December 2015 Plack::Middleware::Debu g
  • 93. London Perl Workshop 12th December 2015 Plack::Debugger • Plack::Debugger is a replacement for Plack::Middleware::Debug • Harder to configure • More flexible • Work in progress • Worth watching
  • 94. London Perl Workshop 12th December 2015 Testing PSGI Apps
  • 95. London Perl Workshop 12th December 2015 Testing Web Apps • Testing web apps is hard • For the same reasons as debugging • WWW::Mechanize • Selenium
  • 96. London Perl Workshop 12th December 2015 Plack::Test • The simple Plack specification makes it easy to write a testing layer • Plack::Test • Standard for all PSGI apps • Dancer2::Test (for example) is now deprecated
  • 97. London Perl Workshop 12th December 2015 Using Plack::Test • Three modes of use • Examples all require the following • use Plack::Test; use HTTP::Request::Common;
  • 98. London Perl Workshop 12th December 2015 Positional Params • my $app = sub { return [ 200, [], [ "Hello "] ] }; my $client = sub { my $cb = shift; my $res = $cb->(GET "/"); is $res->content, "Hello"; }; test_psgi $app, $client;
  • 99. London Perl Workshop 12th December 2015 Named Params • my $app = sub { return [ 200, [], [ "Hello "] ] }; my $client = sub { my $cb = shift; my $res = $cb->("GET /"); is $res->content, “Hello”; } test_psgi app => $app, client => $client;
  • 100. London Perl Workshop 12th December 2015 Object Oriented • my $app = sub { return [ 200, [], [ "Hello "] ] }; my $test = Plack::Test->create($app); my $res = $test->request(GET "/"); is $res->content, "Hello";
  • 101. London Perl Workshop 12th December 2015 Deploying PSGI Apps
  • 102. London Perl Workshop 12th December 2015 Deploying PSGI Apps • PSGI separates implementation from deployment • This is a major advantage • Concentrate on the right problems at the right time • Easily switch between deployment environments
  • 103. London Perl Workshop 12th December 2015 PSGI Server Support • Many new web servers support PSGI • Starman, Starlet, Twiggy, Corona, HTTP::Server::Simple::PSGI • Perlbal::Plugin::PSGI
  • 104. London Perl Workshop 12th December 2015 PSGI Server Support • nginx support • mod_psgi • Plack::Handler::Apache2
  • 105. London Perl Workshop 12th December 2015 Plack::Handler::Apache2 • <Location /psgi> SetHandler perl-script PerlResponseHandler Plack::Handler::Apache2 PerlSetVar psgi_app /path/to/app.psgi </Location>
  • 106. London Perl Workshop 12th December 2015 Deploy Under nginx • Use plackup to start the app • plackup -S Starman app.psgi – Starman is a high-performance preforking PSGI/Plack web server • Configure nginx to proxy requests to port 5000
  • 107. London Perl Workshop 12th December 2015 Advertisement • Deployment will be covered in far more detail on the extended course • We will have practical sessions trying out various deployment scenarios • We will turn our app into a real service • See http://mgnm.at/trn2015
  • 108. London Perl Workshop 12th December 2015 Summary
  • 109. London Perl Workshop 12th December 2015 CGI Summary • CGI is dead – Or, at least, it should be • Don't use CGI for new development • If you must maintain CGI code see CGI::Alternatives • Switch to PSGI
  • 110. London Perl Workshop 12th December 2015 PSGI/Plack Summary • PSGI is a specification • Plack is an implementation/toolbox • PSGI makes your life easier • Most of the frameworks and servers you use already support PSGI • No excuse not to use it
  • 111. London Perl Workshop 12th December 2015 Further Information • perldoc PSGI • perldoc Plack • http://plackperl.org/ • http://blog.plackperl.org/ • http://github.com/miyagawa/Plack • #plack on irc.perl.org
  • 112. London Perl Workshop 12th December 2015 That's all folks • Any questions?