SlideShare a Scribd company logo
Dancer
(the Effortless Perl Web Framework)
About me
●   Sawyer X
●   Sysadmin / Perl Ninja
●   Israel.pm / Haifa.pm / TelAviv.pm / Rehovot.pm
●   I do system, networking, web, applications, etc.
●   http://blogs.perl.org/users/sawyer_x/
●   http://search.cpan.org/~xsawyerx/
Perl web recap




    1995
    CGI
Perl web recap



               2010
    Many frameworks
(including micro-frameworks like Dancer)
The big web religions, illustrated
Ruby – the fanboys
Python – the sticklers
PHP – the nonsensical
Perl – the nutcases
Nutcases?
●   Yes, we are insane (but not LISP-insane)
●   Insanity is a whole lot of fun!
●   Insanity gives us flexibility
●   Flexibility gives us cool stuff
●   Like Moose and meta-programming
●   Like DBIx::Class
●   Like Dancer
Flask (Pythonese)
from flask import Flask
app = Flask(__name__)


@app.route("/", methods=['GET'])
def hello():
    return "Hello World!"


if __name__ == "__main__":
    app.run()
Dancer (Perlesque)
use Dancer;


get “/hi” => sub {
    “Hello, World!”
};


dance;
In comparison
from flask import Flask            use Dancer;
app = Flask(__name__)


@app.route("/", methods=['GET'])   get “/” => sub {
def hello():                         “Hello, World!”
    return "Hello World!"
                                   };
if __name__ == "__main__":
    app.run()                      dance;
Dancer treats
●   Both read and write, easily!
●   Route-based (started as a port of Sinatra)
●   PSGI/Plack compliant (PSGI is our WSGI)
●   Minimum dependencies
●   Any app is also a web server
●   CPAN-friendly (<3 CPAN)
Recipe for Dancing
●   Take an HTTP method
●   Add a path to that
●   Mix with a subroutine
●   And sprinkle plugins and keywords on top
Dancer route structure
get     '/path' => sub { … };
post    '/path' => sub { … };
put     '/path' => sub { … };
del     '/path' => sub { … };
options '/path' => sub { … };
any     '/path' => sub { … };
Dancer
●   Paths can contain variables
    get '/hello/:entity/'


●   Paths can be Regular Expressions
    get qr{/ (w+) / d{2,3} (.+)? }x
Dancer login example
post '/login' => sub {
    # Validate the username and password
    if ( params­>{user} eq 'bob' &&
         params­>{pass} eq 'LetMeIn' ) {


        session user => params­>{user};
        redirect params­>{path} || '/';
    } else {
        redirect '/login?failed=1';
    }
 };
Templating
get '/' => sub {
    template index => {
        greeting => 'welcome'
    }
};
More nifty stuff
●   headers 'My­X­Header' => 'Value'
●   send_file('report.tar.gz')
●   set_cookie name    => 'value',
               expires => ( time + 3600 ),
               domain  => 'foo.com'
●   status 'not_found'
●   to_json, to_yaml, to_xml
●   my $file        = upload('file_input')
●   my $all_uploads = request­>uploads
Dancer as Perl philosophy
●   Dancer is succinct, efficient and easy to work with
●   Dancer is daring
    (Do you have route caching in Django?)
    (Websockets in near future!)
●   Dancer has a lot of plugins:
    (engines for sessions, logging, templates)
●   Serializers (JSON, YAML, XML)
●   Route filters (before, after, before_template)
Oh yeah, route caching...
Dancer::Plugin::REST
get '/user/:id.:format' => sub {
    UserRS­>find( params­>{id} );
};
# curl http://mywebservice/user/42.json
{ "id": 42, "name": "John Foo",             
"email": "john.foo@hopkins.com" }
# curl http://mywebservice/user/42.yml
­­
id: 42
name: "John Foo"
email: "john.foo@hopkins.com"
Dancer::Plugin::SiteMap
    use Dancer::Plugin::SiteMap;


●   You get: /sitemap and /sitemap.xml
●   “Yup, it's that simple.”
Dancer::Plugin::Email
post '/contact' => sub {
    email {
        to      => 'a@b.com',
        subject => 'Test',
        message => $msg,
        attach  => [ path => 'name' ],
    }
};
Dancer::Plugin::Authorize
post '/login' => sub {
    my $user = params­>{'user'};
    my $pass = params­>{'pass'};
    if ( auth( $user, $pass ) ) {
        if ( auth_asa('guest')  ) {...}
        if ( auth_can('create') ) {...}
    }
};
Dancer::Plugin::Ajax
    ajax '/check_for_update' => sub {
        # some ajax code
    };

●   Pass if X-Request-With not “XMLHttpRequest”
●   Disable the layout
●   The action built is a POST request
Dancer::Plugin::DBIC
●   DBIC (DBIx::Class) – a sophisticated ORM
●   Configure the connection in the config file
●   Make the ResultSets available in routes
Dancer::Plugin::Database
●   Database(s) connection in Dancer
    get '/widget/view/:id' => sub {
       my $sth = database­>prepare(
            'select * from widgets where id = ?'
       );
       $sth­>execute( params­>{id} );
       template display_widget => {
           widget => $sth­>fetchrow_hashref,
       };
    };
In culmination
  Dancer is beautiful and fun
The way programming should be



        PerlDancer.org
search.cpan.org/perldoc?Dancer
Perl Dancer for Python programmers
Ad

Recommended

Writing webapps with Perl Dancer
Writing webapps with Perl Dancer
Alexis Sukrieh
 
Perl Dancer, FPW 2010
Perl Dancer, FPW 2010
Alexis Sukrieh
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)
xSawyer
 
Dancing Tutorial
Dancing Tutorial
Alberto Simões
 
An introduction to Rex - FLOSS UK DevOps York 2015
An introduction to Rex - FLOSS UK DevOps York 2015
Andy Beverley
 
Dancer's Ecosystem
Dancer's Ecosystem
Alexis Sukrieh
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Jeremy Kendall
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
Yusuke Wada
 
Developing apps using Perl
Developing apps using Perl
Anatoly Sharifulin
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
Jeremy Kendall
 
RESTful web services
RESTful web services
Tudor Constantin
 
Modern Perl Web Development with Dancer
Modern Perl Web Development with Dancer
Dave Cross
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and Knockout
Vic Metcalfe
 
Perl web frameworks
Perl web frameworks
diego_k
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
Jeremy Kendall
 
Mojo as a_client
Mojo as a_client
Marcus Ramberg
 
Quality Use Of Plugin
Quality Use Of Plugin
Yasuo Harada
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
hendrikvb
 
Mojolicious
Mojolicious
Marcos Rebelo
 
Lessons Learnt in 2009
Lessons Learnt in 2009
pratiknaik
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
Adam Wiggins
 
Webrtc mojo
Webrtc mojo
bpmedley
 
JSON and the APInauts
JSON and the APInauts
Wynn Netherland
 
Mojolicious - A new hope
Mojolicious - A new hope
Marcus Ramberg
 
How to develop modern web application framework
How to develop modern web application framework
techmemo
 
優しいWAFの作り方
優しいWAFの作り方
techmemo
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
Your own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with Ruby
Lindsay Holmwood
 
Perl dancer
Perl dancer
Marian Marinov
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Alberto Perdomo
 

More Related Content

What's hot (20)

Developing apps using Perl
Developing apps using Perl
Anatoly Sharifulin
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
Jeremy Kendall
 
RESTful web services
RESTful web services
Tudor Constantin
 
Modern Perl Web Development with Dancer
Modern Perl Web Development with Dancer
Dave Cross
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and Knockout
Vic Metcalfe
 
Perl web frameworks
Perl web frameworks
diego_k
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
Jeremy Kendall
 
Mojo as a_client
Mojo as a_client
Marcus Ramberg
 
Quality Use Of Plugin
Quality Use Of Plugin
Yasuo Harada
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
hendrikvb
 
Mojolicious
Mojolicious
Marcos Rebelo
 
Lessons Learnt in 2009
Lessons Learnt in 2009
pratiknaik
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
Adam Wiggins
 
Webrtc mojo
Webrtc mojo
bpmedley
 
JSON and the APInauts
JSON and the APInauts
Wynn Netherland
 
Mojolicious - A new hope
Mojolicious - A new hope
Marcus Ramberg
 
How to develop modern web application framework
How to develop modern web application framework
techmemo
 
優しいWAFの作り方
優しいWAFの作り方
techmemo
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
Your own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with Ruby
Lindsay Holmwood
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
Jeremy Kendall
 
Modern Perl Web Development with Dancer
Modern Perl Web Development with Dancer
Dave Cross
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and Knockout
Vic Metcalfe
 
Perl web frameworks
Perl web frameworks
diego_k
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
Jeremy Kendall
 
Quality Use Of Plugin
Quality Use Of Plugin
Yasuo Harada
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
hendrikvb
 
Lessons Learnt in 2009
Lessons Learnt in 2009
pratiknaik
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
Adam Wiggins
 
Webrtc mojo
Webrtc mojo
bpmedley
 
Mojolicious - A new hope
Mojolicious - A new hope
Marcus Ramberg
 
How to develop modern web application framework
How to develop modern web application framework
techmemo
 
優しいWAFの作り方
優しいWAFの作り方
techmemo
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
Your own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with Ruby
Lindsay Holmwood
 

Similar to Perl Dancer for Python programmers (20)

Perl dancer
Perl dancer
Marian Marinov
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Alberto Perdomo
 
Talking Heads - writing an API does not need to be a "psycho killer"
Talking Heads - writing an API does not need to be a "psycho killer"
Theo van Hoesel
 
Web Server-Side Programming Techniques
Web Server-Side Programming Techniques
guest8899ec02
 
Why Python Web Frameworks Are Changing the Web
Why Python Web Frameworks Are Changing the Web
joelburton
 
Lecture 3 - Comm Lab: Web @ ITP
Lecture 3 - Comm Lab: Web @ ITP
yucefmerhi
 
Cgi
Cgi
Girish Srivastava
 
Web Development in Perl
Web Development in Perl
Naveen Gupta
 
Swing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and Sinatra
Matt Gifford
 
Ruby openfest
Ruby openfest
Panagiotis Papadopoulos
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
LaunchAny
 
From zero to almost rails in about a million slides...
From zero to almost rails in about a million slides...
david_e_worth
 
Dancer tutorial | Perl
Dancer tutorial | Perl
Chankey Pathak
 
Sinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящее
.toster
 
Ruby projects of interest for DevOps
Ruby projects of interest for DevOps
Ricardo Sanchez
 
Ricardo Sanchez - Ruby projects of interest for devops
Ricardo Sanchez - Ruby projects of interest for devops
SVDevOps
 
Rack
Rack
Sarah Allen
 
Wider than rails
Wider than rails
Alexey Nayden
 
Web Development Environments: Choose the best or go with the rest
Web Development Environments: Choose the best or go with the rest
george.james
 
21 Www Web Services
21 Www Web Services
royans
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Alberto Perdomo
 
Talking Heads - writing an API does not need to be a "psycho killer"
Talking Heads - writing an API does not need to be a "psycho killer"
Theo van Hoesel
 
Web Server-Side Programming Techniques
Web Server-Side Programming Techniques
guest8899ec02
 
Why Python Web Frameworks Are Changing the Web
Why Python Web Frameworks Are Changing the Web
joelburton
 
Lecture 3 - Comm Lab: Web @ ITP
Lecture 3 - Comm Lab: Web @ ITP
yucefmerhi
 
Web Development in Perl
Web Development in Perl
Naveen Gupta
 
Swing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and Sinatra
Matt Gifford
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
LaunchAny
 
From zero to almost rails in about a million slides...
From zero to almost rails in about a million slides...
david_e_worth
 
Dancer tutorial | Perl
Dancer tutorial | Perl
Chankey Pathak
 
Sinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящее
.toster
 
Ruby projects of interest for DevOps
Ruby projects of interest for DevOps
Ricardo Sanchez
 
Ricardo Sanchez - Ruby projects of interest for devops
Ricardo Sanchez - Ruby projects of interest for devops
SVDevOps
 
Web Development Environments: Choose the best or go with the rest
Web Development Environments: Choose the best or go with the rest
george.james
 
21 Www Web Services
21 Www Web Services
royans
 
Ad

More from xSawyer (13)

do_this and die();
do_this and die();
xSawyer
 
XS Fun
XS Fun
xSawyer
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)
xSawyer
 
Asynchronous programming FTW!
Asynchronous programming FTW!
xSawyer
 
Moose - YAPC::NA 2012
Moose - YAPC::NA 2012
xSawyer
 
Our local state, my, my - Understanding Perl variables
Our local state, my, my - Understanding Perl variables
xSawyer
 
Your first website in under a minute with Dancer
Your first website in under a minute with Dancer
xSawyer
 
Moose talk at FOSDEM 2011 (Perl devroom)
Moose talk at FOSDEM 2011 (Perl devroom)
xSawyer
 
When Perl Met Android (YAPC::EU 2010)
When Perl Met Android (YAPC::EU 2010)
xSawyer
 
Perl Dancer on Android (first attempt)
Perl Dancer on Android (first attempt)
xSawyer
 
Source Code Management systems
Source Code Management systems
xSawyer
 
Moose (Perl 5)
Moose (Perl 5)
xSawyer
 
Red Flags in Programming
Red Flags in Programming
xSawyer
 
do_this and die();
do_this and die();
xSawyer
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)
xSawyer
 
Asynchronous programming FTW!
Asynchronous programming FTW!
xSawyer
 
Moose - YAPC::NA 2012
Moose - YAPC::NA 2012
xSawyer
 
Our local state, my, my - Understanding Perl variables
Our local state, my, my - Understanding Perl variables
xSawyer
 
Your first website in under a minute with Dancer
Your first website in under a minute with Dancer
xSawyer
 
Moose talk at FOSDEM 2011 (Perl devroom)
Moose talk at FOSDEM 2011 (Perl devroom)
xSawyer
 
When Perl Met Android (YAPC::EU 2010)
When Perl Met Android (YAPC::EU 2010)
xSawyer
 
Perl Dancer on Android (first attempt)
Perl Dancer on Android (first attempt)
xSawyer
 
Source Code Management systems
Source Code Management systems
xSawyer
 
Moose (Perl 5)
Moose (Perl 5)
xSawyer
 
Red Flags in Programming
Red Flags in Programming
xSawyer
 
Ad

Recently uploaded (20)

Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
PyCon SG 25 - Firecracker Made Easy with Python.pdf
PyCon SG 25 - Firecracker Made Easy with Python.pdf
Muhammad Yuga Nugraha
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
"Database isolation: how we deal with hundreds of direct connections to the d...
"Database isolation: how we deal with hundreds of direct connections to the d...
Fwdays
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Safe Software
 
AI VIDEO MAGAZINE - June 2025 - r/aivideo
AI VIDEO MAGAZINE - June 2025 - r/aivideo
1pcity Studios, Inc
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
OpenPOWER Foundation & Open-Source Core Innovations
OpenPOWER Foundation & Open-Source Core Innovations
IBM
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
Fwdays
 
Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
PyCon SG 25 - Firecracker Made Easy with Python.pdf
PyCon SG 25 - Firecracker Made Easy with Python.pdf
Muhammad Yuga Nugraha
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
"Database isolation: how we deal with hundreds of direct connections to the d...
"Database isolation: how we deal with hundreds of direct connections to the d...
Fwdays
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Safe Software
 
AI VIDEO MAGAZINE - June 2025 - r/aivideo
AI VIDEO MAGAZINE - June 2025 - r/aivideo
1pcity Studios, Inc
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
OpenPOWER Foundation & Open-Source Core Innovations
OpenPOWER Foundation & Open-Source Core Innovations
IBM
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
Fwdays
 

Perl Dancer for Python programmers