NAME

Dancer2::Manual::Migration - Migrating from Dancer to Dancer2

VERSION

version 0.155002

Migration from Dancer 1 to Dancer2

This document covers some changes that users will need to be aware of while upgrading from Dancer (version 1) to Dancer2.

Apps

1. In Dancer2, each module is a separate application with its own namespace and variables. You can set the application name in each of your Dancer2 application modules. Different modules can be tied into the same app by setting the application name to the same value.

For example, to set the appname directive explicitly:

MyApp:

package MyApp;
use Dancer2;
use MyApp::Admin

hook before => sub {
    var db => 'Users';
};

get '/' => sub {...};

1;

MyApp::Admin:

package MyApp::Admin;
use Dancer2 appname => 'MyApp';

# use a lexical prefix so we don't override it globally
prefix '/admin' => sub {
    get '/' => sub {...};
};

1;

Without the appname directive, MyApp::Admin would not have access to variable db. In fact, when accessing /admin, the before hook would not be executed.

See Dancer2::Cookbook for details.

2. The following modules can be used to speed up an app in Dancer2:

They would need to be installed separately. This is because Dancer2 does not incorporate any C code, but it can get C-code compiled as a module. Thus, these modules can be used for speed improvement provided:

  • You have access to a C interpreter

  • You don't need to fatpack your application

Plugins: plugin_setting

plugin_setting returns the configuration of the plugin. It can only be called in register or on_plugin_import.

Routes

Dancer2 requires all routes defined via a string to begin with a leading slash /.

For example:

get '0' => sub {
    return "not gonna fly";
};

would return an error. The correct way to write this would be to use get '/0'

Tests

Dancer2 recommends the use of Plack::Test.

For example:

use strict;
use warnings;

use Test::More tests => 2;
use Plack::Test;
use HTTP::Request::Common;

{
    package App::Test; # or whatever you want to call it
    get '/' => sub { template 'index' };
}

my $test = Plack::Test->create( App::Test->to_app );
my $res  = $test->request( GET '/' );

ok( $res->is_success, '[GET /] Successful' );
like( $res->content, qr{<title>Test2</title>}, 'Correct title' );

Other modules that could be used for testing are:

Logs

The logger_format in the Logger role (Dancer2::Core::Role::Logger) is now log_format.

read_logs can no longer be used, as with Dancer2::Test. Instead, Dancer2::Logger::Capture could be used for testing, to capture all logs to an object.

For example:

use strict;
use warnings;
use Test::More import => ['!pass'];
use Plack::Test;
use HTTP::Request::Common;

{
    package App;
    use Dancer2;

    set log       => 'debug';
    set logger    => 'capture';

    get '/' => sub {
        debug 'this is my debug message';
        return 1;
    };
}

my $app = Dancer2->psgi_app;
is( ref $app, 'CODE', 'Got app' );

test_psgi $app, sub {
    my $cb = shift;

    my $res = $cb->( GET '/' );
    is $res->code, 200;

    my $trap = App->dancer_app->logger_engine->trapper;

    is_deeply $trap->read, [
        { level => 'debug', message => 'this is my debug message' }
    ];
};

Exports: Tags

The following tags are not needed in Dancer2:

use Dancer2 qw(:syntax);
use Dancer2 qw(:tests);
use Dancer2 qw(:script);

The plackup command should be used instead. It provides a development server and reads the configuration options in your command line utilities.

Engines

Engines now receive a logger that consumes Dancer2::Core::Role::Logger in order to log errors. The attribute is called logger.

The logger engine doesn't have the attribute since it is the logger itself.

Serializers

You no longer need to implement the loaded method. It is simply unnecessary.

Configuration

server_tokens

The configuration server_tokens has been introduced in the reverse (but more sensible, and Plack-compatible) form as no_server_tokens.

DANCER_SERVER_TOKENS changed to DANCER_NO_SERVER_TOKENS.

Keywords

load

This keyword is no longer required. Dancer2 loads the environment automatically and will not reload any other environment when called with load. (It's a good thing.)

param_array

This keyword doesn't exist in Dancer2.

session

The session keyword has multiple states:

  • No arguments

    Without any arguments, the session keyword returns a Dancer2::Core::Session object, which has methods for read, write, and delete.

    my $session = session;
    $session->read($key);
    $session->write( $key => $value );
    $session->delete($key);
  • Single argument (key)

    If a single argument is provided, it is treated as the key, and it will retrieve the value for it.

    my $value = session $key;
  • Two arguments (key, value)

    If two arguments are provided, they are treated as a key and a value, in which case the session will assign the value to the key.

    session $key => $value;
  • Two arguments (key, undef)

    If two arguments are provided, but the second is undef, the key will be deleted from the session.

    session $key => undef;

In Dancer 1 it wasn't possible to delete a key, but in Dancer2 we can finally delete:

# these two are equivalent
session $key => undef;

my $session = session;
$session->delete($key);

AUTHOR

Dancer Core Developers

COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by Alexis Sukrieh.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.