Writing webapps with Perl Dancer

Embed Size (px)

Citation preview

Dancer

A micro framework for writing web applications

Alexis Sukrieh

OSDCfr 2009

Alexis Sukrieh

http://sukria.net

http://twitter.com/sukria

http://search.cpan.org/~sukria/

Dancer

http://dancer.sukria.net$ sudo cpan Dancerhttp://github.com/sukria/Dancer

DescriptionSyntaxApplication TreeEnvironmentsDeployment

webapp framework for Perl

Again, another one !!?

YES.

Why ?

Web Development in Perl

can be :

CGI.pm : fat webapp junkfood

Catalyst : it's huge, but, it's huge.

Plenty of other frameworks alike

Ruby introduced something else

A new approach to webapp development

Perl needed the same

definetly

Kindly stolen from Ruby

So, Dancer is a framework ...

a micro framework

Lightweight

Standalone

PSGI/Plack compliant

expressive syntax

few configuration

painless for the developer

enough talking,

let's dance

Sorry, I mean ...

package MyApp;use Dancer;

get '/' => sub {'Hello OSDCfr 2009!'};

dance;

A dancer script is a webserver

$ ./myApp.pl>> Listening on 127.0.0.1:3000== Entering the development dance floor ...

Working webapp ready to be hacked

happiness : he can WSFC now

DescriptionSyntaxApplication TreeEnvironmentsDeployment

A Dancer app is defined with route handlers

a route handler is basically a sub

bound to an HTTP method (typically 'get' or 'post')

with a path pattern

/foo/bar/:var/baz/*r('/stuff/([a-z0-9]+)/')

Static pattern (path)

//foo/bar/baz

pattern with named tokens

/hello/:buddy

my $name = params->{buddy}

pattern with anonymous tokens

/show/*.*

my ($file, $ext) = splat;

pseudo-regexp-defined patterns

r('/post/([a-z0-9]+)')

my ($post) = splat; # $1

processing a request

=

finding a matching route handler

404

No matching route handler no joy

Route handler found Joy

When found, a route handler is executed

it can alter the response headers

get '/' => sub {content_type 'text/plain';return 'this is plain text'};

pass to the next matching handler

get '/lazy' => sub {pass and return false;};

serve a static file

get '/dowload/:file' => sub {my $file = params->{file};

if (! -f $file) { pass and return false; }

send_file $file;};

throw an error

get '/forbidden' => sub {

send_error 'Nope';

};

redirect to somewhere else

get '/forbidden' => sub {

redirect '/better/place'

};

and of course, render a content

get '/showme' => sub {template 'showme', { var => 'foo'};};

return value

=

content to render

logging ?

get '/' => sub {# ...debug 'here it is';};

logs/development.log

pre-processing ?

before sub { do_some_init_stuff();params->{foo} = 'beenthere';};

static file serving ?

existing file in $appdir/public

=

file served, no handler needed

DescriptionSyntaxApplication TreeEnvironmentsDeployment

app.pl

app.plviews/ index.tt

app.plviews/ index.tt layouts/ main.tt

app.plviews/ index.tt layouts/ main.ttconfig.yml

app.plviews/ index.tt layouts/ main.ttconfig.ymlenvironments/ development.yml production.yml

app.plviews/ index.tt layouts/ main.ttconfig.ymlenvironments/ development.yml production.ymlpublic/

bootstraping ?

$ dancer -a MyApp

+ MyApp+ MyApp/views+ MyApp/views/index.tt+ MyApp/views/layouts+ MyApp/views/layouts/main.tt+ MyApp/environments+ MyApp/environments/development.yml+ MyApp/environments/production.yml+ MyApp/config.yml+ MyApp/app.psgi+ MyApp/MyApp.pm+ MyApp/MyApp.pl+ MyApp/public+ MyApp/public/css+ MyApp/public/css/style.css+ MyApp/public/css/error.css+ MyApp/public/images+ MyApp/public/404.html+ MyApp/public/500.html

Working webapp, pre-configured, pre-designed and waiting for your hacks

DescriptionSyntaxApplication TreeEnvironmentsDeployment

settings : customizing the app

settings in the app code

use Dancer;

set layout => 'application'set foo => 42;set content_type =>'text/plain';

handy at first, but dirty

YAML config files: goodness

# config.yml

layout: 'application'foo: 42content_type: 'text/plain'

config.yml

=

global configuration

environments/foo.yml

foo configuration

$ dancer -e foo

runs the app in foo environment

development.yml

warnings: 1show_errors: 1...

production.yml

warnings: 0show_errors: 0...

show_errors: 1

show_errors: 0

DescriptionSyntaxApplication TreeEnvironmentsDeployment

For production needs,

use PSGI/Plack

Plack is to Perl :

what Rack is to Rubywhat WSGI is to Python

universal

server application

gateway

PSGI/Plack

miyagawahttp://plackperl.org

Dancer supports Plack since 0.9904

app.psgi

tells Plack how to dance

use CGI::PSGI;use MyApp;

my $handler = sub {my $env = shift;my $cgi = CGI::PSGI->new($env);Dancer->dance($cgi);};

The app is now PSGI/Plack aware

$ plackup -a app.psgi &

Webservers have PSGI adapters

Apache (mod_psgi)nginxPerlbalHTTP::Server::FastPlack (standalone)

Conf example with Apache

SetHandler perl-scriptPerlHandler Plack::Server::Apache2PerlSetVar psgi_app /path/app.psgi

Works pretty well

enjoy web development with Perl

DANCE!