Skip to content

Latest commit

 

History

History
143 lines (102 loc) · 4.5 KB

dancer-with-plack-middlewares.pod

File metadata and controls

143 lines (102 loc) · 4.5 KB

How to use Dancer with Plack's middlewares

Plack is an awesome addition to the Perl ecosystem. One of it's key feature are the middlewares.

You can see a middleware as a Role: a reusable components between your applications. This component will act both as a client and a server.

This article doesn't aim to present in detail how a middleware works. If you're not yet familiar with Plack's middleware, you can refer to thoses articles:

http://search.cpan.org/~miyagawa/Plack-0.9951/lib/Plack/Middleware.pm
http://advent.plackperl.org/2009/12/day-10-using-plack-middleware.html

Dancer and Plack

Let's start by creating a simple Dancer application:

$ dancer -a myapp
+ myapp
+ myapp/bin
+ myapp/bin/app.pl
...

Every Dancer application is a valid Plack application. When you're starting your project, you can choose between a standalone server, or using Plack:

$ ./bin/app.pl
>> Dancer server 12481 listening on http://0.0.0.0:3000
== Entering the development dance floor ...

Doing this, it start my application using Dancer's standalone server on port 3000.

Now, let's use Plack to start this application:

$ plackup bin/app.pl
HTTP::Server::PSGI: Accepting connections at http://0:5000/

This time, it's the PSGI's standalone server that serve our application.

Adding a first Middleware

For this example, we will add a basic middleware: Plack::Middleware::ETag. This one will add to all our response a new header: ETag. The ETag is a mechanism to control cache validation. Most of the time, the value of the ETag is a hash of the content of the page returned to the client. The client will then store this value, and next time it requets the same page, he will ask to send the content only if it has been modified since the last request, using the ETag value to check.

In your config.yml, add the following two lines:

plack_middlewares:
  -
    - ETag

now restart your application (with plackup), and let's do a request:

$ curl -D - http://localhost:5000
HTTP/1.0 200 OK
Date: Tue, 09 Nov 2010 15:49:30 GMT
Server: HTTP::Server::PSGI
Content-Type: text/html; charset=UTF-8
X-Powered-By: Perl Dancer 1.1999_02
ETag: 5f6e450f378e384d4be6e0c081b9dd93026ff146
Content-Length: 5428

The ETag header have been added to your response. If you redo the request, you'll see that the ETag value is the same.

Let's add another middleware: Plack::Middleware::ConditionalGet. This middleware return no content if the client requested the content only if it had been modified since the previous request:

plack_middlewares:
  - 
    - ConditionalGET
  -
    - ETag

(note: the order is important).

$ curl -D - http://localhost:5000 -H "If-None-Match: 5f6e450f378e384d4be6e0c081b9dd93026ff146"
HTTP/1.0 304 Not Modified
Date: Tue, 09 Nov 2010 15:52:01 GMT
Server: HTTP::Server::PSGI
X-Powered-By: Perl Dancer 1.1999_02
ETag: 5f6e450f378e384d4be6e0c081b9dd93026ff146

This time there is no Content-Lenght header, because the value of the ETag header is the same, so no content has been returned to our request.

Using the Debug panels

One very useful middleware while debuging your application is Plack::Middleware::Debug. This middleware will inject some HTML code in your page.

XXXXX insert screenshot

More complexe

Some middlewares require a more complex configuration, and you won't use them as in our previous examples. For this example, we want to add a simple authentication system to access our application.

Edit your bin/app.pl application, and replace the code with this one:

use Dancer;
use myapp;

use Plack::Builder;

my $app = sub {
    my $env     = shift;
    my $request = Dancer::Request->new($env);
    Dancer->dance($request);
};

builder {
    enable "Auth::Basic", authenticator => sub {
        my ( $username, $password ) = @_;
        return $username eq 'admin' && $password eq 's3cr3t';
    };
    $app;
};

First, we create a PSGI application (line 5). This application process the request and returns a PSGI compatible result. Next, we use the builder keyword, provided by Plack::Builder. Here we enable a middleware (Auth::Basic), and we create a code ref for the authentication method.

If you start your application with plackup, and load the page in your browser, you will be prompted for a username and password to access the page.