Dancer Advent Calendar 2014
http://advent.perldancer.org/
Past and future
http://advent.perldancer.org/2014/24
perlhttp://advent.perldancer.org/2014/24Wed, 24 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="past_and_future"></a>Past and future</h1>
<p>This last article is meant to reflect on the past, in the present,
and speculate about the future, perhaps even - with the cover of
darkness - offer some future plans, in quiet murmur, of course. :)</p>
<h2><a name="popularity"></a>Popularity</h2>
<p>We all care about popularity. Popularity isn't just cool factor, it's
also a measurement of success - doing well, going in the right direction.</p>
<p>But how do you measure popularity? It's
<a href="http://blog.timbunce.org/2008/04/12/tiobe-or-not-tiobe-lies-damned-lies-and-statistics/">hard</a>.</p>
<p>We have different mechanisms made just to measure success. In our
world that would Github stars, Github watchers, and even MetaCPAN
votes. However, if you take a look at Moose, it only has 78 stars on Github, and
only 15 watchers. Would you say Moose is less successful than Dancer? Not
at all. This measurement simply is far from accurate.</p>
<p>However, there is another way to measure popularity.</p>
<p>One of my favorite and most respected authors provides the following
comment in all of his projects:</p>
<p><i>All complex software has bugs lurking in it, and this module is no
exception. If you find a bug please either email me, or add the bug to
cpan-RT.</i></p>
<p>Complex software accumulates tickets. These are bugs, feature requests,
failing tests, missing tests, questions, and so on. Hopefully authors
will collect these in a ticket system like RT or Github.</p>
<p>The amount of tickets you have indicates how many of these came up. While
some authors will open a staggering amount of tickets for their projects
(which is nothing short of being thorough and responsible) and projects
may have a devoted user who opens tickets upon tickets, most tickets are
opened by the audience of users. The number indicates how many have used your
software to a degree of contacting you, providing input, and found you or
your project approachable and tried to help improve it.</p>
<p>You can count the number of tickets for a project, remove the core authors
(and check for when they weren't core authors yet - it happens sometimes),
normalize to amount of users opening the issues, and look at the numbers.</p>
<p>Dancer has two main repositories: Dancer 1 and Dancer 2. Together they have
accumulated around 1,900 tickets. Yes, that's close to <b>two thousand</b>
tickets. About 1,000 of them are pull requests. Yes, that's right. Over
<b>one thousand</b> pull requests. Actually, my numbers are off. I only took
into account Github. Dancer has been running on RT earlier and there's a
quite a few there as well. That would also be off, because we accept
tickets through any medium. We get them in personal emails, on the mailing
list, at conferences, on IRC, and so on.</p>
<p>Beyond all measurements, I'd say we reached people. More importantly,
I would say these people reached us. I cannot be more proud of this
achievement.</p>
<p>I can talk about <a href="http://www.booking.com">Booking</a> using Dancer. I can
talk about <a href="http://www.shutterstock.com">Shutterstock</a> using Dancer. I can
talk about <a href="http://www.moonfruit.com">MoonFruit</a>, <a href="http://www.uk2.net">UK2</a>,
<a href="https://www.tilt.com">Tilt</a>, <a href="https://www.financejobs.co">FinanceJobs</a>,
<a href="http://perlmaven.com">PerlMaven</a>, <a href="http://geekuni.com">Geekuni</a>, the
<a href="http://www.strehler-cms.org">Strehler CMS</a>, and even a
<a href="http://www.finchleyspiritualistchurch.org.uk">spiritual church</a> and
an <a href="http://theanarchistlibrary.org">anarchist library</a> using Dancer.</p>
<p>I can talk about all of these, but that's not the great part. The great
part is our contributors.</p>
<h2><a name="contribution_is_key"></a>Contribution is key</h2>
<p>Having someone contributing their time and skill is priceless. Contributors
are the life-force of a project - not the core developers. Almost any
core developer in Free and Open Source will undoubtedly tell you that
development's gratitude is someone using it, thanking you for it, or better
yet, improving it further by contributing something - a test, a documentation
patch, or even opening tickets.</p>
<p>Except for Dancer's founder, Alexis (<i>@sukria</i>) Sukrieh, all Dancer core
developers started as contributors. This includes yours truly and everyone
else in the team. This hasn't changed since. We always saw and see ourselves
simply as contributors with more responsibility.</p>
<p>Dancer has enjoyed the help of an astonishing amount of contributors. Overall,
the Dancer project has received contributions from over 270 people. While this
seems big it fails to account for many contributors and many forms of
contribution. It's merely the number of recognized code committers.</p>
<p>Sam Batschelet organized the Dancer conference, Gabor Szabo took the Dancer
website under his care, Peter Martini provided a Dancer Docker image, David
Dick packages the project for Fedora, Paul Cochrane is working on improving
the documentation for beginners, and there are numerous other examples for
tremendous work done by the community.</p>
<p>Let me take a moment to thank you all for the work you've done and the
work that you do, in the community and for the community.</p>
<p>So now, where is all of this heading?</p>
<h2><a name="what_the_future_holds___"></a>What the future holds...</h2>
<p>It's hard to say what the future holds for Dancer, but we do have quite
a few plans.</p>
<p>The short list contains:</p>
<ul>
<li><a name="item_Thorough_documentation_overhaul"></a><b>Thorough documentation overhaul</b>
</li>
<li><a name="item_Improve_the_plugin_system_for_Dancer2"></a><b>Improve the plugin system for Dancer2</b>
</li>
<li><a name="item_Port_all_useful_plugins_to_Dancer2"></a><b>Port all useful plugins to Dancer2</b>
</li>
<li><a name="item_Rewrite_fair_portions_of_the_testing_suite"></a><b>Rewrite fair portions of the testing suite</b>
</li>
<li><a name="item_Many_core_cleanups"></a><b>Many core cleanups</b>
</li>
<li><a name="item_Additional_functionality"></a><b>Additional functionality</b>
</li>
<li><a name="item_Speed_optimizations"></a><b>Speed optimizations</b>
</li>
<li><a name="item_Compatibility_shims"></a><b>Compatibility shims</b>
</li>
<li><a name="item_Code_linting"></a><b>Code linting</b>
</li>
</ul>
<p>We even have some idea regarding features we want to introduce:</p>
<ul>
<li><a name="item_Full_asynchronous_support"></a><b>Full asynchronous support</b>
</li>
<li><a name="item_Route_naming"></a><b>Route naming</b>
</li>
<li><a name="item_Chained_hooks"></a><b>Chained hooks</b>
</li>
<li><a name="item_Stronger_command_line_tooling"></a><b>Stronger command line tooling</b>
</li>
<li><a name="item_More_decoupling_of_components"></a><b>More decoupling of components</b>
</li>
</ul>
<p>As you can see, there are plenty of ideas and the opportunities are abound.</p>
<p>While we want to add some of these features as quickly as possible, we
need to make sure we get them right, that we design them well, that we
do not overlap with other features, and that we don't have to revert them.</p>
<p>In fact, what we need is your help.</p>
<p>I can promise some will be difficult to implement, some will take
considerable time, and some will be like trudging through mud (especially
any OS compatibility work), but above all, I can promise you will have a good
time. :)</p>
<p>I would like to thank everyone for an amazing year. I hope to see you and
work with you this new year and provide you all with another set of articles
at the next Advent Calendar.</p>
<p>Have a merry Christmas, a wonderful Hanukkah, and a tremendous Festivus,
for the rest of us!</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Dynamic routing in Dancer is dynamic
http://advent.perldancer.org/2014/23
perlhttp://advent.perldancer.org/2014/23Tue, 23 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="dynamic_routing_in_dancer_is_dynamic"></a>Dynamic routing in Dancer is dynamic</h1>
<p>Dancer provides with a number of ways to do dynamic routing, A.K.A.,
chained actions. Let's take a look at situations that lead to such
a requirement and how to achieve it.</p>
<h2><a name="the_use_case"></a>The use-case</h2>
<p>Let's say you were building a message board that supported any number of
boards - each with a custom URL. For example, if this were something for a
Beethoven fan site you might have a board for discussing each genre of work
composed by him, with URLs like:</p>
<ul>
<li><a name="item_http___www_beethovenfans_com_string_quartets_"></a><b>http://www.beethovenfans.com/string-quartets/</b>
</li>
<li><a name="item_http___www_beethovenfans_com_symphonies_"></a><b>http://www.beethovenfans.com/symphonies/</b>
</li>
<li><a name="item_http___www_beethovenfans_com_piano_sonatas_"></a><b>http://www.beethovenfans.com/piano-sonatas/</b>
</li>
</ul>
<p>Visiting the top-level board url would show you a list of all posts under
that board. You could start a discussion by simply using <i>/new-post</i> under
the board name. So to start a discussion under string-quartets, you'd go to:</p>
<pre class="prettyprint">http://www.beethovenfans.com/string-quartets/new-post</pre>
<p>Similarly, you could view or permalink to a specific post as:</p>
<pre class="prettyprint">http://www.beethovenfans.com/string-quartets/opus-18-no-6</pre>
<p>Where <i>opus-18-no-6</i> is the unique identifier of the post - possibly generated
from the title of the post.</p>
<p>Similarly, to upvote a post on the board:</p>
<pre class="prettyprint">http://www.beethovenfans.com/string-quartets/opus-18-no-6/upvote</pre>
<p>Each time someone accesses one of these URLs, you first need to check if the
discussion board exists. To put it in code:</p>
<pre class="prettyprint">get '/:board' => sub {
my $board = param('board');
# validation code for $board
...
};
get '/:board/new-post' => sub {
my $board = param('board');
# validation code for $board
};
get '/:board/opus-18-no-6/upvote' => sub {
my $board = param('board');
# validation code for $board
};</pre>
<p>Each of these handlers have to start by validating the existence of a
discussion board before they do anything else. It makes sense to have the
discussion board validation logic in one place.</p>
<h2><a name="setup_method"></a>Setup method</h2>
<p>One way to do this is by defining a special setup method which you call
when the application starts up. This method can use the <b><code>prefix</code></b>
keyword to set up routes for each board.</p>
<pre class="prettyprint">sub get_boards {
# in a real life application this would come from a
# database. for the sake of simplicity, we simply return
# a hard-coded list
return qw(string-quartets symphonies piano-sonatas piano-trios);
}
sub setup_routes {
my @boards = get_boards;
foreach my $board (@boards) {
prefix "/$board" => sub {
# any variables here will be accessible to the handlers
# defined below
my $welcome_message = "Welcome to the group for discussing: $board";
get '/' => sub {
# show a list of all the posts under the board $board
# for demo's sake simply return the welcome message
return $welcome_message;
};
get '/:post_id' => sub {
# do the work here or delegate to a specialised class
my $post_id = param('post_id');
# check if the ID is valid and do something with it
# for demo's sake show variables you have access to:
return "I was called with board: $board, post id: $post_id"
. " and have access to the welcome_message variable: $welcome_message";
};
};
}
}</pre>
<p>Then in your app.pl:</p>
<pre class="prettyprint">#!/usr/bin/env perl
use FindBin;
use lib "$FindBin::Bin/../lib";
use beethoven;
beethoven->setup_routes;
beethoven->to_app;</pre>
<p>Calling setup_routes essentially materialises the routes beforehand based on
what <code>get_boards</code> returns. If the user enters a board that doesn't exist, it
will automatically get picked up by Dancer's default handling of missing
routes and a 404 error will be returned to the user.</p>
<p>This approach works well if the number of boards is small. Say in hundreds,
or may be in thousands, but not in hundreds of thousands. After a certain
point the Dancer process will grow too big in memory. That might or might
not be a problem depending on your infrastructure.</p>
<p>Also if boards are not fixed and are created all the time then this approach
will not work very well as it would required an app restart to pick up all
the new boards (or for that matter changes to the URL slugs for the existing
boards, or deletions).</p>
<h2><a name="the_hook"></a>The hook</h2>
<p>There is another way that allows us to dynamically check for a board rather
than materialising all our routes up front. The basic idea is to combine
<b><code>prefix</code></b> with a <b><code>before</code></b> handler. Let's put together some
code to illustrate this idea:</p>
<pre class="prettyprint">hook before => sub {
my $board = param('board');
if ($board && board_is_valid($board)) {
var board => $board;
}
};
prefix '/:board' => sub {
get '/' => sub {
# show a list of all the posts under the board $board
# for demo's sake simply return the welcome message
my $board = var('board') or pass;
my $welcome_message = "Welcome to the group for discussing: $board";
return $welcome_message;
};
get '/:post_id' => sub {
my $board = var('board') or pass;
# do the work here
my $post_id = param('post_id');
# check if the ID is valid and do something with it
# for demo's sake show variables you have access to:
return "I was called with board: $board, post id: $post_id";
};
};
sub board_is_valid {
my $board = shift;
return if not defined $board;
# in a real life application we would check this against a table in
# a database or through a backend service. for the sake of
# simplicity, let's just check against a hardcoded list
my %valid_boards = map { $_ => 1 }
qw(string-quartets symphonies piano-sonatas piano-trios);
return defined $valid_boards{$board};
}</pre>
<p>This time, our <code>before</code> handler will catch the request first. It sets up
the <code>board</code> variable using <b><code>var</code></b> that is automatically passed around
to each handler. The handler first checks if the <code>board</code> variable exists
and if it doesn't, it simply defers the handling to the Dancer's default
route handling. Since no other routes to handle the <code>:board</code> exist, this
results in a 404.</p>
<p>While it alleviates the need to build all possible routes
up front, the one downside to this approach is having to check for the
presence of <code>board</code> variable in each handler. On the positive side, you can
dynamically add boards without restarting the application for them to be
available.</p>
<h2><a name="even_more_ways"></a>Even more ways</h2>
<p>Additional approaches for the dynamic route handling problem exist. Most
notably, another approach was recently documented by Yanick Champoux uses
<a href="http://www.perladvent.org/2013/2013-12-02.html">megasplat</a> to produce
<a href="http://techblog.babyl.ca/entry/chained-dancer">chained actions</a>.</p>
<h2><a name="minimum_version"></a>Minimum version</h2>
<p>This article requires <a href="https://metacpan.org/module/Dancer2">Dancer2</a> version 0.159000.</p>
<p><i>(hopefully released soon enough.)</i></p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Dancer has many methods of producing dynamic routes (or "chained actions") and
each of them has its benefits and drawbacks.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Deepak Gulati for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>Creative Commons Deepak Gulati 2014.</p>
</div>The Dancer community policy
http://advent.perldancer.org/2014/22
perlhttp://advent.perldancer.org/2014/22Mon, 22 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="the_dancer_community_policy"></a>The Dancer community policy</h1>
<p>In October 2014 we have introduced our Dancer core and community policy
and our Standards of Conduct. You can find them at <a href="https://metacpan.org/module/Dancer::Policy">Dancer::Policy</a>
or <a href="https://metacpan.org/module/Dancer2::Policy">Dancer2::Policy</a> (identical documents).</p>
<p>While the Dancer community has always pride itself of the warm feeling
members have received, helpfulness and kindness were abundant, we still
found it necessary to introduce a policy document.</p>
<h2><a name="why_do_we_need_it"></a>Why do we need it?</h2>
<p>While the policy is not an answer to a situation in the Dancer community,
it is to behavior we've seen in other communities in and out of the tech
industry.</p>
<p>There are people who are not only discriminated against, but also
marginalized daily. There are people who feel pushed out of the way, made
small and insignificant, and dis-empowered by others who tend to have a
more favorable starting point - what is usually referred to as
"privileged".</p>
<p>We felt it is absolutely crucial to provide a document that makes it
absolutely clear, without a shadow of a doubt, that the Dancer community
is maintained and owned by its members - all having a fair and equal
stance in it. It is essential that everyone in the community feel and
understand this space belongs to them just as much as it does to anyone
else.</p>
<h2><a name="introducing_a_problem_where_none_exists"></a>Introducing a problem where none exists?</h2>
<p>So, are we really just fixing a situation that is not broken? If all is
fine and well in the Dancer community, why provide such standards of
conduct? That's a good question.</p>
<p>Standards of conduct have multiple purposes:</p>
<ul>
<li><a name="item_Set_expectations_of_behavior"></a><b>Set expectations of behavior</b>
<p>It is important that people in the community are aware of both what is
expected from them (such as "you are expected to not be abusive towards
anyone") and what they can expect from others (such as "you can expect
not to be abused by anyone"). Setting these expectations allows people to
let their guard down, enjoy their time, approach others, and be an active
member without fearing abuse.</p>
<p>The community, above all, should be a <b>safe space</b> for all of its members.</p>
</li>
<li><a name="item_Provide_a_stern_warning"></a><b>Provide a stern warning</b>
<p>The document clearly explains that not only do we have expectations, but
we will take measures against those who violate them. This helps defend the
expectations we described above.</p>
<p>If you will violate those standards, we will make sure you are held
accountable. This makes sure these are not empty promises and that they won't
be perceived as such.</p>
</li>
<li><a name="item_Enforcement_transparency"></a><b>Enforcement transparency</b>
<p>While we provide these standards and a promise to enforce them, it is also
important to provide transparency. You need to know <i>what</i> will be done
and <i>how</i> decisions will be made.</p>
</li>
</ul>
<h2><a name="can_i_still_be_me"></a>Can I still be me?</h2>
<p>Many people worry that with a standards of conduct policy they will not be
able to be themselves anymore. This is worth addressing.</p>
<p>The standards of conduct clearly stipulate you may not, under any
circumstance, be abusive to others. If violating that robs you of your
being, it means you are an abusive person - a person we hope other
community members will not have to experience or deal with.</p>
<p>This, however, is not the same as "I will need to watch what I say".
Having to make an effort to be kinder, more composed, or in general more
respectful, is an understood effort. It is an effort we make every day. We
make sure we're more respectful towards our friends, colleagues, peers,
and we make sure we curse much less around our parents.</p>
<p>While it is not always a simple task to work on our behavior, it is far
different than violating your core principles.</p>
<p>In short, if your core principles are to hurt others, and you feel like
our standards of conduct negate that, we've done a good job.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>The community is maintained by the community members. Each and every single
member should be regarded with respect, and we should all feel a sense of
belonging to and in our community.</p>
<p>The Dancer standards of conduct have been introduced to make sure new members
understand this and know what we each expect from each other.</p>
<p>We were thrilled with getting such positive results from a community. Members
have unequivocally said we are happy to make this message clear to all current
and future members.</p>
<h2><a name="thanks"></a>Thanks</h2>
<p>Praise should be given to <code>#p5p</code> (The Perl 5 Porters list) which provided the
base for the policy document, to <a href="http://twitter.com/sungo">@sungo</a> for pushing
to make community standards published clearly and for doing so with the Perl
IRC servers, and to <a href="https://metacpan.org/author/RIBASUSHI">ribasushi</a> for
helping revise and suggest improvements to the policy as it was being written.</p>
<p>The biggest thanks is, as always, to the wonderful and loving Dancer community
and all of its members. :)</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Middlewared Dancer: our usage of middlewares
http://advent.perldancer.org/2014/21
perlhttp://advent.perldancer.org/2014/21Sun, 21 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="middlewared_dancer__our_usage_of_middlewares"></a>Middlewared Dancer: our usage of middlewares</h1>
<p>Now that we understand what
<a href="http://advent.perldancer.org/2014/20">middlewares</a> are and how to use
them, we would like to share a small secret with which we ended the
previous article.</p>
<p>While much of the existing middlewares provide additional features, there
are middlewares that can help supplement a web framework or reduce the
amount of work it does.</p>
<p>In <a href="https://metacpan.org/module/Dancer2">Dancer2</a> we rely heavily on Plack and therefore middlewares provide
much-appreciated help which plays well with our framework, since it's all
<a href="https://metacpan.org/module/PSGI">PSGI</a> at the end of the day.</p>
<p>Here are the current middlewares we use internally in Dancer2:</p>
<h2><a name="static"></a>Static</h2>
<p>First, as described in
<a href="http://advent.perldancer.org/2014/6">a previous article</a>,
Dancer2 now uses <a href="https://metacpan.org/module/Plack::Middleware::Static">Plack::Middleware::Static</a> to provide static files.</p>
<p>This helped provide consistency with both the previous behavior
(a la Dancer 1) and with how users actually expect static file serving
to work.</p>
<h2><a name="head"></a>Head</h2>
<p>Using <a href="https://metacpan.org/module/Plack::Middleware::Head">Plack::Middleware::Head</a>, we can provide correct <b>HEAD</b> requests
much more easily. A <b>HEAD</b> request should not have a body, and the
middleware simply deletes the body of a response if the request method is
<b>HEAD</b>.</p>
<p>This allows us to define every <b>GET</b> request as <b>HEAD</b> and have the
middleware delete the response body to produce an appropriate response.</p>
<p>One less concern!</p>
<h2><a name="contentlength"></a>ContentLength</h2>
<p>Originally Dancer2 would have to set the length of a response content body
every time it was set. Although this could have been improved by only
setting it at the very end, we would still have to account for three kinds
of responses available in PSGI.</p>
<p>Instead, we're using <a href="https://metacpan.org/module/Plack::Middleware::ContentLength">Plack::Middleware::ContentLength</a> to decide and set
the <b>Content-Length</b> header for us after we've returned a response. Our
code is thus cleaner and less error-prone.</p>
<h2><a name="fixmissingbodyinredirect"></a>FixMissingBodyInRedirect</h2>
<p>Having <a href="https://metacpan.org/module/Plack::Middleware::FixMissingBodyInRedirect">Plack::Middleware::FixMissingBodyInRedirect</a> provides the proper
response body when a user returns a redirect. You don't have to care about
it anymore, it's simply there, automagically.</p>
<h2><a name="removeredundantbody"></a>RemoveRedundantBody</h2>
<p>When returning a status of <b>204</b> or <b>304</b> the body needs to be stripped.</p>
<p><a href="https://metacpan.org/module/Plack::Middleware::RemoveRedundantBody">Plack::Middleware::RemoveRedundantBody</a> takes care of that for us. Since
it uses <a href="https://metacpan.org/module/Plack::Util">Plack::Util</a>'s <code>status_with_no_entity_body</code>, it also takes care
of statuses <b>100</b> and <b>101</b>, which were not covered beforehand.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>When writing a web framework, you (or at least we) would
like to focus on the features and richness of the DSL and syntax, and not
the small details of HTTP implementations.</p>
<p>Using middlewares reduces the amount of work we do to keep up with all of
these small bits and does a damn fine job at it.</p>
<p>We will continue to explore new middlewares we can make use of, and perhaps
even push some of our code into middlewares so it could be decoupled and
even used by non-Dancer code.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Meddling with Middlewares
http://advent.perldancer.org/2014/20
perlhttp://advent.perldancer.org/2014/20Sat, 20 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="meddling_with_middlewares"></a>Meddling with Middlewares</h1>
<p><a href="https://metacpan.org/module/Plack">Plack</a> provides a useful component called a
<a href="https://metacpan.org/module/Plack::Middleware">Middleware</a>, which wraps applications with
functionality.</p>
<p>You can use them to your advantage to tack on additional features and
improvements to your application.</p>
<h2><a name="middleware_usage"></a>Middleware usage</h2>
<p>Adding middlewares can be breeze using the <a href="https://metacpan.org/module/Plack::Builder">Plack::Builder</a> syntax:</p>
<pre class="prettyprint">use MyApp;
use Plack::Builder;
builder {
enable 'Auth::Basic', authenticator => sub {
my ( $user, $pass, $env ) = @_;
# test $user and $pass somehow
};
MyApp->to_app;
};</pre>
<p>Since <code>to_app</code> returns an app, you can use it as the last statement
to <code>builder</code>. In this example we add <code>Plack::Middleware::Auth::Basic</code>
middleware to our new application stack.</p>
<p>We can add more:</p>
<pre class="prettyprint">builder {
enable 'Auth::Basic', authenticator => sub { ... };
enable 'Rewrite', rules => sub {
return 301
if s{^/foo/?$}{/bar/}
or s{^/baz/?$}{/quux/};
...
};
MyApp->to_app;
};</pre>
<p>Now having <code>Plack::Middleware::Rewrite</code> as well. Having it before
<i>Auth::Basic</i> will assure the rewrites will happen first. Having it
after <i>Auth::Basic</i> will assure authentication will happen first.</p>
<h2><a name="multiple_dancer_applications"></a>Multiple Dancer applications</h2>
<p>As explained in our <code>to_app</code>
<a href="http://advent.perldancer.org/2014/9">article</a>, you can set up multiple
<a href="https://metacpan.org/module/Dancer2">Dancer2</a> applications using the same syntax:</p>
<pre class="prettyprint">use MyApp;
use MyApp::Admin;
use Plack::Builder;
builder {
mount '/' => MyApp->to_app;
mount '/admin' => MyApp::Admin->to_app;
};</pre>
<p>We can still add middlewares to that stack:</p>
<pre class="prettyprint">builder {
enable 'Rewrite', rules => sub {
...
};
mount '/' => MyApp->to_app;
mount '/admin' => MyApp::Admin->to_app;
};</pre>
<p>Not bad, but there's one more situation to cover.</p>
<h2><a name="going_nuts"></a>Going nuts</h2>
<p>Let's take a look at another situation: adding authentication using a
middleware:</p>
<pre class="prettyprint">builder {
enable 'Auth::Basic', authenticator => sub { ... };
mount '/' => MyApp->to_app;
mount '/admin' => MyApp::Admin->to_app;
};</pre>
<p>But wait. This doesn't make sense. We want to only enable authentication
for the <i>admin</i> application. This will set it up to both of them.</p>
<p>Since the Dancer application is a callback, and <code>builder</code> wraps
callbacks by providing another callback... you might see where this is
heading:</p>
<pre class="prettyprint">builder {
mount '/' => MyApp->to_app;
mount '/admin' => builder {
enable 'Auth::Basic', authenticator => sub { ... };
MyApp::Admin->to_app;
};
};</pre>
<p>Pretty cool, huh? Very!</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Middlewares are awesome and very easy to integrate with Dancer. In fact,
we use middlewares internally in <a href="https://metacpan.org/module/Dancer2">Dancer2</a>, which you will read
about in the next article.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Authentication for the masses
http://advent.perldancer.org/2014/19
perlhttp://advent.perldancer.org/2014/19Fri, 19 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="authentication_for_the_masses"></a>Authentication for the masses</h1>
<p>Just like at some point every developer writes a templating system,
every web developer eventually writes a form for authentication.</p>
<p>It's simple: we check the user credentials on a request and decide whether
to continue or redirect them to a form. The form allows them to submit
their username and password and we save that and create a session for them
so when they now try the original request, we recognize them and allow them
in.</p>
<h2><a name="basic_application"></a>Basic application</h2>
<p>The application is fairly simple. We have a route that needs
authentication, we have a route for showing the login page, and we have a
route for posting login information and creating a session.</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
get '/' => sub {
session('user')
or redirect('/login');
template index => {};
};
get '/login' => sub {
template login => {};
};
post '/login' => sub {
my $username = param('username');
my $password = param('password');
my $redir_url = param('redirect_url') || '/login';
$username eq 'john' && $password eq 'correcthorsebatterystaple'
or redirect $redir_url;
session user => $username;
redirect $redir_url;
};</pre>
<h2><a name="tiny_authentication_helper"></a>Tiny authentication helper</h2>
<p><a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Tiny">Dancer2::Plugin::Auth::Tiny</a> allows you to
abstract away not only the part that checks whether the session exists, but to
also generate a redirect with the right path and return URL.</p>
<p>We simply have to define what routes needs a login using Auth::Tiny's
<code>needs</code> keyword.</p>
<pre class="prettyprint">get '/' => needs login => sub {
template index => {};
};</pre>
<p>It creates a proper return URL using <code>uri_for</code> and the address from
which the user arrived - something we didn't do ourselves.</p>
<p>We can thus decorate all of our private routes to require authentication
in this simple manner. If a user does not have a session, it will
automatically forward it to <code>/login</code>, in which we would render a form
for the user to send a login request.</p>
<p>Auth::Tiny even provides us with a new parameter, <code>return_url</code>, which we
can use to send the user back to their original requested path.</p>
<p>We will still need to handle the password verification, but we have yet
another small helper for this.</p>
<h2><a name="password_hashing"></a>Password hashing</h2>
<p>Many web developers don't understand the importance of hashing passwords.
There are many articles to explain this, but few spend the time
to read and understand them. From the multitude of methods available, and
the different hashing alogrithms out there, it's not a simple task to
decide on which combination to use and how.</p>
<p><a href="https://metacpan.org/module/Dancer2::Plugin::Passphrase">Dancer2::Plugin::Passphrase</a> (recently ported from Dancer 1) provides
a simple passwords-as-objects interface with sane defaults for hashed
passwords which you can use in your web application. It uses <b>bcrypt</b>
as the default but supports anything the <a href="https://metacpan.org/module/Digest">Digest</a> interface does.</p>
<p>Assuming we have the original user-creation form submitting a username
and password:</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
use Dancer2::Plugin::Passphrase;
post '/register' => sub {
my $username = param('username');
my $password = passphrase( param('password') )->generate;
# $password is now a hashed password object
save_user_in_db( $username, $password->rfc2307 );
template registered => { success => 1 };
};</pre>
<p>We can now add the <b>POST</b> method for verifying that username and
password:</p>
<pre class="prettyprint">post '/login' => sub {
my $username = param('username');
my $password = param('password');
my $saved_pass = fetch_password_from_db($username);
if ( passphrase($password)->matches($saved_pass) ) {
session user => $username;
redirect param('return_url') || '/';
}
# let's render instead of redirect...
template login => { error => 'Invalid username or password' };
};</pre>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Both <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Tiny">Dancer2::Plugin::Auth::Tiny</a> and <a href="https://metacpan.org/module/Dancer2::Plugin::Passphrase">Dancer2::Plugin::Passphrase</a>
are simple wrappers around basic functionality. You can check their code,
it's pretty simple and straight-forward.</p>
<p>The strength of plugins are not necessarily in complicated and weird code,
but rather in abstracting difficult things to remember and get right, and
making them accessible in your web environment and integrated with your
application configuration.</p>
<p>Authentication is not just easier with these modules, but safer.</p>
<p>You might also want to read up on <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Extensible">Dancer2::Plugin::Auth::Extensible</a>.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>The method of the setup method
http://advent.perldancer.org/2014/18
perlhttp://advent.perldancer.org/2014/18Thu, 18 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="the_method_of_the_setup_method"></a>The method of the setup method</h1>
<p>Load-time setup of application variables depends on the availability of
the configuration options, but we often have the requirement of being
able to defer these to later. But how do we do this?</p>
<h2><a name="a_common_requirement"></a>A common requirement</h2>
<p>Many applications set up variables on load-time:</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
my $dsn = config->{'dsn'};
my $schema = MyApp::Schema->connect($dsn);
...</pre>
<p><i>(If you're using the <a href="https://metacpan.org/module/Dancer2::Plugin::Database">Dancer2::Plugin::Database</a>, a similar thing
will happen behind the scenes.</i></p>
<p>The problem we have with this is that it requires the information to
be available in the configuration (accessed via the <code>config</code> keyword)
before loading the application.</p>
<pre class="prettyprint">use MyApp; # config() will be called</pre>
<p>What happens when we want to set up the variables beforehand?</p>
<p><i>I can do that</i>, you think to yourself. Here's the code:</p>
<pre class="prettyprint">use Dancer2; # for config() keyword
use MyApp;
config->{'dsn'} = $new_dsn; # too late, hot plate!</pre>
<p>Nope. Not going to work. When you call <code>use MyApp</code>, it will already
use the <code>config</code> keyword to get the DSN.</p>
<p>Alright, so you decide to change the configuration before you load the
second application. Let's try that.</p>
<pre class="prettyprint">use Dancer2;
config->{'dsn'} = $new_dsn;
use MyApp;</pre>
<p>But that's not going to work, because <code>use</code> is compile-time, not
run-time. The order is actually as following:</p>
<pre class="prettyprint">use Dancer2; # happens first
config->{'dsn'} = $new_dsn; # happens last
use MyApp; # happens right after "use Dancer2"</pre>
<p>You might think you could get around this with <code>BEGIN</code> by forcing the
changes to happen before it loads the application:</p>
<pre class="prettyprint">BEGIN {
use Dancer2;
config->{'dsn'} = $new_dsn;
use MyApp;
}</pre>
<p>Sure. That will control the order of events by forcing the <code>config</code>
statement to get called at compile-time, and because it's one line before
the <code>use MyApp</code> line, it will be called before it. Oh wait...</p>
<p>Now you've hit a major design issue with <a href="https://metacpan.org/module/Dancer2">Dancer2</a>. We no longer play
with globals because globals are evil. This means that as soon as you
called <code>use Dancer2</code>, we created an application based on your package
name.</p>
<p>When you change the configuration (using the <code>config</code> keyword), you
change the configuration of the first application built. When you called
<code>use MyApp</code>, <a href="https://metacpan.org/module/Dancer2">Dancer2</a> had created yet another application, solely for
the <i>MyApp</i> package. This is fully intended and is a major leading
design for Dancer2.</p>
<p>But how do we still handle this reasonable requirement?</p>
<h2><a name="moving_to_run_time"></a>Moving to run-time</h2>
<p>Instead of trying to elevate the setup code to compile-time, why not just
push the application setup to run-time instead?</p>
<p>What if we loaded the code and imported it in runtime?</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
my $dsn;
sub setup {
$dsn = config->{'dsn'};
# do something with $dsn
get '/' => sub {...};
}</pre>
<p>Now we just call <code>setup</code> method when we want to
start registering routes. It's a good start. Let's make it accept
parameters:</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
my $dsn
sub setup {
my $opts = shift;
$dsn = $opts->{'dsn'} || config->{'dsn'};
# do something with $dsn
get '/' => sub {...};
}</pre>
<p>Now we can call it from some other environment:</p>
<pre class="prettyprint"># mytest.t:
...
use MyApp;
MyApp->setup({ dsn => 'dbi:SQLite:dbname=:memory:' });</pre>
<p>We can even set up our own schema object if we put that functionality
in our <code>setup</code> method:</p>
<pre class="prettyprint">my $test_dsn = 'dbi:SQLite:dbname=t/corpus/test.sqlite';
my $schema = MyApp::Schema->connect($test_dsn);
MyApp->setup({ schema => $schema });
$schema->deploy;
...</pre>
<h2><a name="the_future"></a>The future</h2>
<p>Since this is such a useful bootstrapping pattern, we are still
considering adding this as a built-in feature in <a href="https://metacpan.org/module/Dancer2">Dancer2</a>. While you
can roll your own this easily, we could envision making this even easier.</p>
<p>Imagine having a <code>bootstrap</code> method which could be run before the routes
are registered or when you actually call <code>to_app</code>, with optional
bootstrap callbacks. It is possible and we might just blog about it
in the future.</p>
<p>Meanwhile, Dancer applications have just enough magic to do great things
while still allowing you to make use of Perl to get around load-order
and encapsulation issues.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Hidden feature: Auto Pages
http://advent.perldancer.org/2014/17
perlhttp://advent.perldancer.org/2014/17Wed, 17 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="hidden_feature__auto_pages"></a>Hidden feature: Auto Pages</h1>
<p>One feature we love in Dancer (both <a href="https://metacpan.org/module/Dancer">Dancer 1</a> and
<a href="https://metacpan.org/module/Dancer2">Dancer 2</a>) is the <i>AutoPage</i> feature.</p>
<h2><a name="auto_what"></a>Auto-what?</h2>
<p>Most websites provide web pages - multiple web pages. Many web pages will
have a template and not just static content.</p>
<p>Rendering a template is simple:</p>
<pre class="prettyprint">get '/users/view' => sub {
template 'view' => {...};
};</pre>
<p>Assuming we have over 40 different pages, this becomes an arduous task of
writing endpoints for each template, then keeping those up-to-date and
continuing to add more.</p>
<p>If only. If only someone would have come up with a feature that allowed
automatically rendering templates by path. If only someone named
<b>David Precious</b>, who is now handling the absurd responsibility of
fatherhood while leaving <b>Sawyer X</b> to handle the
<a href="http://advent.perldancer.org">Dancer Advent Calendar</a> all on his own,
would have that idea and have already implemented it in Dancer 1, thus
having it available from the early days of Dancer 2... oh wait, he did!</p>
<h2><a name="how"></a>How</h2>
<p><i>AutoPage</i> is a simple feature that you would love. Turning it on is
as simple as:</p>
<pre class="prettyprint">set auto_page => 1;</pre>
<p>or in your configuration file:</p>
<pre class="prettyprint">auto_page: 1</pre>
<p>Dancer will take care of the rest.</p>
<p>At this point, you might be wondering what it really does.</p>
<h2><a name="behind_the_scenes"></a>Behind the scenes</h2>
<p>What <i>AutoPage</i> does is very simple: when a request was not served by a
static file or by a user defined route, it looks for a template that
matches the path. If it finds one, it renders it.</p>
<p>This means that the request <code>/users/edit</code> will first try to match a
file, failing that it will try to match a route, and then, if still
unsuccessful, it will go to <i>AutoPage</i>. <i>AutoPage</i> will search for
a template under <code>views/users/</code> named <code>edit.tt</code>, assuming your <i>views</i>
directory is <code>views</code> and your templating engine default extension is
<code>.tt</code>.</p>
<p><i>AutoPage</i> will adhere to your <code>views</code> and your templating system
extension, so if those change, it will still work. It will also not
render the layouts themselves, so you don't need to worry about someone
being a smart-ass.</p>
<h2><a name="another_reason_it_s_awesome"></a>Another reason it's awesome</h2>
<p>By fully rendering a template, not just statically serving it, you
have the full range of request variables. That means that any code in
your templates that requires variables (or callbacks) will work:</p>
<pre class="prettyprint"># in layout/main.tt:
Served by [% dancer_version %]</pre>
<p>This will work just fine. But what about variables we're adding in
our code using the <code>before_template_render</code> hook?</p>
<pre class="prettyprint"># in MyApp.pm:
use Time::HiRes 'time';
hook before_template_render => sub {
my $tokens = shift;
$tokens->{'timestamp'} = time;
};
# in users/edit.tt:
Request timestamp: [% timestamp %]</pre>
<p>Why would you put the timestamp there? I don't know. It's yet another
contrived example that shows how you can add variables that will be
accessible to the template rendered by <i>AutoPage</i>.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>The <i>AutoPage</i> feature is probably one of the nicest subtle features
in Dancer. We don't hide it, but we also don't make it abundantly clear
to users how awesome it is and how you most likely want to use it.</p>
<p>At the end of the day, this feature also serves as yet another reason
to buy David Precious a drink, which will finally force him to come
to some public Perl event. This is all part of our secret plan.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Command line dancing
http://advent.perldancer.org/2014/16
perlhttp://advent.perldancer.org/2014/16Tue, 16 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="command_line_dancing"></a>Command line dancing</h1>
<p>Some of the changes <a href="https://metacpan.org/module/Dancer2">Dancer2</a> has introduced were the removal of all
import tags:</p>
<pre class="prettyprint">use Dancer ':syntax'; # use Dancer2;
use Dancer ':script'; # use Dancer2;
use Dancer ':tests'; # use Dancer2;</pre>
<p>Now you simply call <code>use Dancer2</code> for all of these. It will create an
application and provide keywords. If you want to create a <a href="https://metacpan.org/module/PSGI">PSGI</a>
application from it, simply call <code>to_app</code> on your class. Otherwise,
it doesn't get in the way.</p>
<h2><a name="but_i_need_it"></a>But I need it</h2>
<p>While the last paragraph actually summed up this entire article, it
probably wasn't very clear.</p>
<p>A useful feature of going through Dancer itself is that it will read
the configuration files, parse them, understand them, and even create
objects lazily using them.</p>
<p>People often write scripts that have to then duplicate what Dancer
does. It's quite understandable that people wish to be able to use
Dancer in their scripts to have access to the configuration and the
generated objects.</p>
<h2><a name="reaching_the_config"></a>Reaching the config</h2>
<p>By importing <a href="https://metacpan.org/module/Dancer2">Dancer2</a> in your command line scripts, you have full
access to the configuration using the imported keywords:</p>
<pre class="prettyprint"># myscript.pl:
use Dancer2; # strict && warnings included
# this works:
my $appname = config->{'appname'};
# and so does this:
my $appname = app->name;</pre>
<p>You shouldn't worry about <i>myscript.pl</i> becoming an app and starting
a web server. Yes, as soon as it hits <code>use Dancer2</code> it will create
a Dancer2 application behind the scenes, and that app can be run at
any given point in time by calling <code>dance</code> or the preferred method
<code>to_app</code> on it, but unless you actually call those, this app will
simply be created in the background.</p>
<p>You will still be able to access all the configuration from it without
having to run it under a web environment.</p>
<h2><a name="small_example"></a>Small example</h2>
<p>One small example of wanting to access the configurations from a command
line script would be to run some sort of import to or export from a
database.</p>
<p>Being able to access the configuration file and having the classes that
are automatically inflated from that configuration file is mighty useful.</p>
<pre class="prettyprint"># myscript.pl:
use Dancer2
use Dancer2::Plugin::Database;
my $user_id = $ARGV[0] or die "$0 <USER ID>\n";
$user_id =~ /^[0-9]+$/ or die "User ID must be a positive number\n";
my $sth = database->prepare( 'select * from users where id = ?' );
$sth->execute($user_id);
...</pre>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>If you want to create command line applications that use the Dancer2
structures, you can simply load Dancer2 and use the keywords it provides
you.</p>
<p>What does this give you access to?</p>
<ul>
<li><a name="item_Dancer_keywords"></a><b>Dancer keywords</b>
<p><code>config</code> probably being the most helpful one, but <code>template</code> will also
be available just like other engine-related keywords are - explained
below under <i>Engines</i>.</p>
</li>
<li><a name="item_Keywords_created_by_plugins"></a><b>Keywords created by plugins</b>
<p>This means you can make use of any functionality they provide outside of
a request.</p>
</li>
<li><a name="item_Engines"></a><b>Engines</b>
<p>This means you can use the facilities your web application has when
logging events (using <code>debug</code>, <code>warning</code>, and <code>error</code>), accessing or
setting session information, serializing, and even rendering templates
(using the <code>template</code> keyword).</p>
</li>
</ul>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Outreach Program for Women (OPW) and Dancer
http://advent.perldancer.org/2014/15
perlhttp://advent.perldancer.org/2014/15Mon, 15 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="outreach_program_for_women__opw__and_dancer"></a>Outreach Program for Women (OPW) and Dancer</h1>
<p>The <a href="https://opw.gnome.org">Outreach Program for Women</a> (OPW) helps
women work on Open Source and Free Software applications while
receiving a salary and having a mentor by their side.</p>
<p><a href="http://www.perlfoundation.org/">The Perl Foundation</a> (TPF) is
<a href="http://www.perlfoundation.org/outreach_program_for_women">participating</a>
this year again, and this year we have the pleasure of participating
with Dancer!</p>
<h2><a name="our_participant"></a>Our participant</h2>
<p>Our applicant, Snigdha Dagar, has been accepted to work on <a href="https://metacpan.org/module/Dancer2">Dancer2</a>'s
documentation overhaul!</p>
<p>She had already contributed the first draft of the
<a href="https://metacpan.org/module/Dancer2::Manual::Migration">Dancer2::Manual::Migration</a> document to help users with upgrading from
<a href="https://metacpan.org/module/Dancer">Dancer</a> to <a href="https://metacpan.org/module/Dancer2">Dancer2</a>.</p>
<h2><a name="the_documentation_overhaul"></a>The documentation overhaul</h2>
<p>The documentation overhaul was deemed a crucial component in making the
upgrading from Dancer 1 to Dancer 2 more attainable.</p>
<p>The current documentation has been copied over from Dancer 1, but is not
completely compatible. Some things have changed and many features have
been added. Unfortunately in the frenzy of continuing upgrading Dancer
and its abilities, along with important improvements, we lack the tuits
to resolve the outstanding problems with the current documentation.</p>
<p>Starting from scratch would be a tremendous amount of work, and whether
it will be less or more work than going through the current documentation
with a fine comb and sorting it out still does not resolve the problem
with the lack of personnel for this task.</p>
<p>What we need is human resources - and not the department. :)</p>
<h2><a name="there_is_a_plan"></a>There is a plan</h2>
<p>Snigdha has provided a plan for overhauling the documentation, which
includes researching other FOSS projects, provide introductory material,
How-to guides, and cohesiveness of the overall documentation.</p>
<p>Her work will help resolve the documentation problems, assure consistency,
accuracy, and above all, a well structured, helpful documentation for such
an important project.</p>
<h2><a name="there_will_be_updates"></a>There will be updates</h2>
<p>We are excited and delighted to have her help in these upcoming months
and we will be providing updates on the progress made.</p>
<p>We are certain Snigdha would appreciate any guidance and assistance from
the community. Feel free to suggest corrections, improvements, what to
focus on, what to not focus on, and how to assure the success of her work
and the project.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Writing plugins for Dancer2
http://advent.perldancer.org/2014/14
perlhttp://advent.perldancer.org/2014/14Sun, 14 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="writing_plugins_for_dancer2"></a>Writing plugins for Dancer2</h1>
<p>Plugins provide you with additional keywords to decouple
predefined behavior to make it easier on you so you won't need to
implement the same thing over and over again.</p>
<p>Let me show you how simple it is to write a plugin of your own.</p>
<p><i>(This explains the current API to plugins. Refer to
<a href="https://metacpan.org/module/Dancer2::Plugin">Dancer2::Plugin</a> for up-to-date documentation.)</i></p>
<h2><a name="a_plugin_that_does_nothing__so_far_"></a>A plugin that does nothing (so far)</h2>
<p>All you need to do is use <a href="https://metacpan.org/module/Dancer2::Plugin">Dancer2::Plugin</a> and that will provide
you with all the keywords you need to write the plugin.</p>
<pre class="prettyprint">package Dancer2::Plugin::Kitteh;
use Dancer2::Plugin;
# we do nothing, just like most cats do
register_plugin;
1;</pre>
<h2><a name="introducing_keywords"></a>Introducing keywords</h2>
<p>You can introduce new keywords the application will receive when it
uses your plugin using the <code>register</code> keyword:</p>
<pre class="prettyprint">register meow => sub {
my ( $dsl ) = plugin_args(@_);
my $app = $dsl->app;
};</pre>
<p>This is how we introduce the <code>meow</code> keyword to the user.</p>
<p>We use <code>plugin_args</code> to make sure we get the plugin arguments. This
is for compatibility.</p>
<p>The keyword receives an object which represents the DSL object the
app is connected to. You can use it in order to access the Dancer2
core application connected to the user's scope.</p>
<p>We can also control whether a keyword is <i>app-global</i>, meaning it
can be called from anywhere in an app or only from a route,
which means during a request:</p>
<pre class="prettyprint">register meow => sub {
debug 'Meow!';
}, { is_global => 0 };</pre>
<h2><a name="route_decorators"></a>Route decorators</h2>
<p>Some plugins generate routes from other routes, which makes them look
a little bit like route decorators. Take <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Tiny">Dancer2::Plugin::Auth::Tiny</a>
for example:</p>
<pre class="prettyprint">get '/private' => needs login => sub { ... };</pre>
<p>The way it works is by taking the route sub as a parameter and creating
its own route which calls it. We can do the same.</p>
<pre class="prettyprint">package Dancer2::Plugin::OnTuesday;
# ABSTRACT: Make sure a route only works on Tuesday
use Dancer2::Plugin;
register on_tuesday => sub {
my ( $dsl, $route_sub, @args ) = plugin_args(@_);
my $day = (localtime)[6];
$day == 2 or return pass;
return $route_sub->( $dsl, @args );
};
register_plugin;</pre>
<p>Now we can use this plugin as such:</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
use Dancer2::Plugin::OnTuesday;
get '/' => on_tuesday => sub { ... };
# every other day
get '/' => sub { ... };</pre>
<h2><a name="reading_the_configuration"></a>Reading the configuration</h2>
<p>While a user can change the configuration using both the configuration file
and the <code>set</code> keyword, we need a single source for all configuration
options for our plugin. This is handled automatically using the
<code>plugin_setting</code> keyword:</p>
<pre class="prettyprint">register meow => sub {
my $dsl = shift;
my $vol = plugin_setting->{'volume'} || 3;
};</pre>
<h2><a name="extra_tricks"></a>Extra tricks</h2>
<p>There are a few additional tricks available which weren't covered here,
such as running code on import, registering additional hooks, and
executing hooks. They are all documented in <a href="https://metacpan.org/module/Dancer2::Plugin">Dancer2::Plugin</a>.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>The plugin infrastructure in the upgrade from Dancer 1 to Dancer 2
has been problematic. We've tried various methods to allow plugins to
coexist, then to specify how they work, and finally to provide a
proper shim layer to enable working with both smealessly.</p>
<p>Unfortunately all of these methods had problems and we resulted in
separating the plugins. This does not mean that writing a
plugin for Dancer 2 is difficult. In fact it's fairly simple.</p>
<p>We're working on making them even more comfortable and remove any
lingering problems, but as you can see they are already easy to write.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>The test core: How we test in Dancer2 core
http://advent.perldancer.org/2014/13
perlhttp://advent.perldancer.org/2014/13Sat, 13 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="the_test_core__how_we_test_in_dancer2_core"></a>The test core: How we test in Dancer2 core</h1>
<p>The Dancer2 core test suite is improving significantly. We have made
vast changes in how we
<a href="http://advent.perldancer.org/2014/8">sort our tests</a> and we now use
<a href="https://metacpan.org/module/Plack::Test">Plack::Test</a> to <a href="http://advent.perldancer.org/12">write tests</a>.</p>
<p>If you're interested in contributing, we would not only praise you for
years to come, but also shower you and your family with gifts. But
before you can contribute tests, it's important you understand our
practices and conventions when writing tests.</p>
<h2><a name="basics"></a>Basics</h2>
<p>There are a few guidelines for the tests which we try to maintain
when writing tests:</p>
<ul>
<li><a name="item__code_use_ok__code__for_testing_classes_load"></a><b><code>use_ok</code> for testing classes load</b>
</li>
<li><a name="item_Declare_the_number_of_tests"></a><b>Declare the number of tests</b>
</li>
<li><a name="item_Use__i_subtests__i__or_code_blocks_for_scoping"></a><b>Use <i>subtests</i> or code blocks for scoping</b>
</li>
<li><a name="item_Try_to_reach_as_much_coverage_as_possible"></a><b>Try to reach as much coverage as possible</b>
</li>
<li><a name="item_Reduce_convenience_modules_and_don_t_make_them_mandatory"></a><b>Reduce convenience modules and don't make them mandatory</b>
</li>
<li><a name="item_Thus__skip_if_those_modules_aren_t_available"></a><b>Thus, skip if those modules aren't available</b>
</li>
<li><a name="item_Provide_each_test_with_a_test_name___no_empty_tests"></a><b>Provide each test with a test name - no empty tests</b>
</li>
</ul>
<h2><a name="testing_classes"></a>Testing classes</h2>
<p>The main tests are actually for classes. As
<a href="http://advent.perldancer.org/2014/8">explained</a>, we store these
tests in <i>t/classes/</i>, under a directory for each class we test.</p>
<p>Let's take a look at the <a href="https://metacpan.org/module/Dancer2::Core::Factory">Dancer2::Core::Factory</a> object tests. Since
it simply creates engine objects and contains only a single method,
the test is rather simple.</p>
<p>Boilerplate:</p>
<pre class="prettyprint">use strict;
use warnings;
use Test::More tests => 5;</pre>
<p>As explained, this is not a fast and hard rule, but we prefer to count
the number of tests we have, to make sure the test doesn't miss a test
someone has accidentally put on a condition.</p>
<p>We test loading:</p>
<pre class="prettyprint">use_ok('Dancer2::Core::Factory');</pre>
<p>Then we test the object itself:</p>
<pre class="prettyprint">my $factory = Dancer2::Core::Factory->new;
isa_ok( $factory, 'Dancer2::Core::Factory' );
can_ok( $factory, 'create' );</pre>
<p>You might notice we pick descriptive names. We try to avoid variables
names <code>$f</code> in our core code as well as in our tests.</p>
<p>Now we can test the <code>create</code> method, which is actually a class method,
so holding the factory object is not required. We generally avoid class
methods, but in this class we're a bit more lax about it:</p>
<pre class="prettyprint">my $template = Dancer2::Core::Factory->create(
'template', 'template_toolkit', layout => 'mylayout'
);
isa_ok( $template, 'Dancer2::Template::TemplateToolkit' );
is( $template->{'layout'}, 'mylayout', 'Correct layout set in the template' );</pre>
<p>That's it. Pretty simple.</p>
<h2><a name="testing_dsl"></a>Testing DSL</h2>
<p>In order to test DSL keywords, we need to have a valid application who
uses <code>Dancer2</code> and then try its DSL keywords. That's actually simple
enough.</p>
<p>The test <i>t/dsl/app.t</i> provides our test for the <code>app</code> keyword, which
returns the current <a href="https://metacpan.org/module/Dancer2::Core::App">Dancer2::Core::App</a> a package is using.</p>
<p>First we have our boilerplate:</p>
<pre class="prettyprint">use strict;
use warnings;
use Test::More tests => 2;
use Plack::Test;
use HTTP::Request::Common;</pre>
<p>Now we define an application in the code in its own scope so it doesn't
interfere with the test itself, but be available to it:</p>
<pre class="prettyprint">{
package App;
use Dancer2;
get '/' => sub {
my $app = app;
::isa_ok( $app, 'Dancer2::Core::App' );
::is( $app->name, 'App', 'Correct app name' );
};
}</pre>
<p>This application uses <code>Dancer2</code> and thus receives the keywords. Since
our test is written in the implicit <code>main</code> package, the double colon
shorthand for <code>main::</code> class resolution allows it to call <code>::isa_ok</code>
to reach the test's <code>isa_ok</code> function (provided by <a href="https://metacpan.org/module/Test::More">Test::More</a>) and
<code>::is</code> allows it to reach the test's <code>is</code> function (also provided by
<a href="https://metacpan.org/module/Test::More">Test::More</a>).</p>
<p>This test checks that if you reach the main path, it will call the
<code>app</code> keyword and check it received an instance, that it is the right
instance, and that the name was even set correctly.</p>
<p>We still need to write the code to reach it:</p>
<pre class="prettyprint">Plack::Test->create( App->to_app )->request( GET '/' );</pre>
<p>There.</p>
<p>Often we return values from a web request, but in this specific
case we're really interested in an object which the route receives and
doing it by sending it back as a response would just be overengineering.</p>
<h2><a name="what_about_external_files"></a>What about external files?</h2>
<p>Some tests might require some additional files to work. Perhaps you're
checking the side-effect of reading from the configuration file or a piece
of code that works with the file system.</p>
<p>One example is <i>t/issues/gh-639</i> which has additional directories, each
have their own <i>config.yml</i> and test file to check against different
configuration files as part of a general issue opened.</p>
<h2><a name="conclusions"></a>Conclusions</h2>
<p>Following the guidelines you will be able to help us improve our tests,
move our old ones, and provide new tests for issues you or others might
open.</p>
<p>We're very interested in having a good test coverage and providing
reliable behavior. Tests are a major component of it and we would always
be more than happy to receive more help in that field.</p>
<p>Next time you open an issue, consider writing a test for it. If you're
not sure how, please contact us. We would love to help. :)</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>A test to remember: testing your web application
http://advent.perldancer.org/2014/12
perlhttp://advent.perldancer.org/2014/12Fri, 12 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="a_test_to_remember__testing_your_web_application"></a>A test to remember: testing your web application</h1>
<p>Perl has an extensive culture of testing which originated in the Perl
language itself, carrying a staggering number of tests for its own
features.</p>
<p>We write a multitude of tests for every single bit in our distributions and
we test them across different platforms, setups, versions of modules and
applications, and even on different versions of perl[1] itself.</p>
<p>For non-Perl regulars, you might think I'm exaggerating. Oh no, I'm not.
Check out <a href="http://cpants.cpanauthors.org/">CPANTS, our CPAN Testing Service</a>
for more details on our amazing free Perl testing service.</p>
<p>It's safe to say: we love tests.</p>
<p><i>[1] We use <b>Perl</b> (uppercase) for the language and <b>perl</b> (lowercase)
for the interpreter</i>.</p>
<h2><a name="but_in_the_land_of_web___"></a>But in the land of web...</h2>
<p>In the world of web, testing is trickier. A web application runs on a web
server. That is usually an application written in another language (often
C or C++), a long-running process with lots of configuration files and
behavior that is hard to decouple.</p>
<p><a href="https://metacpan.org/module/LWP">LWP</a> Gave us <a href="https://metacpan.org/module/LWP::UserAgent">LWP::UserAgent</a> which gave us <a href="https://metacpan.org/module/WWW::Mechanize">WWW::Mechanize</a>. As long
as we had a web server running, we could just write some tests (turned on
with an environment variable) that will make requests and test the results,
producing proper TAP. There's even <a href="https://metacpan.org/module/Test::WWW::Mechanize">Test::WWW::Mechanize</a> to make it
smoother.</p>
<p>However, these don't handle the problem with testing in a web environment:
the web server itself.</p>
<h2><a name="enter_psgi"></a>Enter PSGI</h2>
<p>Any web application built on a <a href="https://metacpan.org/module/PSGI">PSGI</a> framework allows to approach the
problem from an entirely different perspective.</p>
<p><a href="https://metacpan.org/module/PSGI">PSGI</a> applications (such as those created with Dancer) are actually
code references fed to a web server. This means that as long as you create
the proper request (specified by the <a href="https://metacpan.org/module/PSGI">PSGI</a> docs), you can call that
application code reference with it and receive a response. No server is
actually necessary. The server is merely there to create a proper
request.</p>
<p><a href="https://metacpan.org/module/Plack">Plack</a>, the set of utilities for <a href="https://metacpan.org/module/PSGI">PSGI</a> applications, comes with a
special module to help this process: <a href="https://metacpan.org/module/Plack::Test">Plack::Test</a>.</p>
<p>What <a href="https://metacpan.org/module/Plack::Test">Plack::Test</a> does is truly fantastic: it receives a common web
request (using standard <a href="https://metacpan.org/module/HTTP::Request">HTTP::Request</a> objects), fakes a web
server in order to create a proper PSGI request, and sends it to the web
application. When the web application returns a PSGI response (which Dancer
applications do), it will then convert it to a common web response (as a
standard <a href="https://metacpan.org/module/HTTP::Response">HTTP::Response</a> object).</p>
<p>This allows you to then create requests in your test, create the code
reference for your web application, call them, and receive a response
object, which you can then test to your heart's delight.</p>
<p>Let's take a look at a few examples.</p>
<h2><a name="basic_example"></a>Basic example</h2>
<p>Assuming we have a web application:</p>
<pre class="prettyprint"># MyApp.pm
package MyApp;
use Dancer2;
get '/' => sub {'OK'};
1;</pre>
<p>Now we want to write a test for it. Let's create <i>base.t</i>:</p>
<pre class="prettyprint"># base.t
use strict;
use warnings;
use Test::More tests => 2;
use Plack::Test;
use HTTP::Request;
use MyApp;</pre>
<p>Now let's create a coderef for our application using the <code>to_app</code> keyword:</p>
<pre class="prettyprint">my $app = MyApp->to_app;</pre>
<p>That was easy. Now let's create a test object from <a href="https://metacpan.org/module/Plack::Test">Plack::Test</a> for our
application:</p>
<pre class="prettyprint">my $test = Plack::Test->create($app);</pre>
<p>Now we can call requests on it. We'll create our first request object and
send it to our test object to receive a response:</p>
<pre class="prettyprint">my $request = HTTP::Request->new( GET => '/' );
my $response = $test->request($request);</pre>
<p>We can now test it:</p>
<pre class="prettyprint">ok( $response->is_success, '[GET /] Successful request' );
is( $response->content, 'OK', '[GET /] Correct content' );</pre>
<h2><a name="putting_it_all_together"></a>Putting it all together</h2>
<p>If we put all our code together and remove some excess, we can come up
with the following test file:</p>
<pre class="prettyprint"># base.t
use strict;
use warnings;
use Test::More;
use Plack::Test;
use HTTP::Request::Common;
use MyApp;
my $test = Plack::Test->create( MyApp->to_app );
my $response = $test->request( GET '/' );
ok( $response->is_success, '[GET /] Successful request' );
is( $response->content, 'OK', '[GET /] Correct content' );
done_testing();</pre>
<p>It might seem like too much boilerplate, but there's enough modules to
help you reduce that.</p>
<h2><a name="subtests"></a>Subtests</h2>
<p>We also separate our tests using <a href="https://metacpan.org/module/Test::More">Test::More</a>'s <code>subtest</code> functionality,
thus creating multiple self-contained tests that don't overwrite each other.</p>
<p>Assuming we have a different app that has two states we want to test.</p>
<pre class="prettyprint"># MyApp.pm
package MyApp;
use Dancer2;
set serializer => 'JSON';
get '/' => sub {
my $user = param('user');
$user and return { user => $user };
return {};
};
1;</pre>
<p>This is a very contrived example of a route that checks for a user
parameter. If it exists, it returns it in a hash with the key 'user'. If
not, it returns an empty hash. Useful? Probably not, but a good example
for having two tests.</p>
<pre class="prettyprint"># param.t
use strict;
use warnings;
use Test::More;
use Plack::Test;
use HTTP::Request::Common;
use MyApp;
my $test = Plack::Test->create( MyApp->to_app );
subtest 'A empty request' => sub {
my $res = $test->request( GET '/' );
ok( $res->is_success, 'Successful request' );
is( $res->content '{}', 'Empty response back' );
};
subtest 'Request with user' => sub {
my $res = $test->request( GET '/?user=sawyer_x' );
ok( $res->is_success, 'Successful request' );
is( $res->content '{"user":"sawyer_x"}', 'Empty response back' );
};
done_testing();</pre>
<p>We could, of course, use <a href="https://metacpan.org/module/JSON">JSON</a> to decode and check for a proper object,
which would be the right thing for a bigger response. Did I say
<i>contrived</i> yet? :)</p>
<h2><a name="cookies"></a>Cookies</h2>
<p>One interesting requirement is being able to handle cookies, mostly used
for maintaining sessions. We can use <a href="https://metacpan.org/module/Test::WWW::Mechanize::PSGI">Test::WWW::Mechanize::PSGI</a> or
<a href="https://metacpan.org/module/LWP::Protocol::PSGI">LWP::Protocol::PSGI</a>, I personally prefer using <a href="https://metacpan.org/module/HTTP::Cookies">HTTP::Cookies</a> directly.</p>
<p>Taking the previous test, assuming it actually creates and uses cookies
for sessions, all we would need is the following:</p>
<pre class="prettyprint"># ... all the use statements
use HTTP::Cookies;
my $jar = HTTP::Cookies->new;
my $test = Plack::Test->create( MyApp->to_app );
my $host = 'http://127.0.0.1';
subtest 'A empty request' => sub {
my $res = $test->request( GET "$host/" );
ok( $res->is_success, 'Successful request' );
is( $res->content '{}', 'Empty response back' );
$jar->extract_cookies($res);
ok( $jar->as_string, 'We have cookies!' );
};
subtest 'Request with user' => sub {
my $req = GET "$host/?user=sawyer_x";
$jar->add_cookie_header($req);
my $res = $test->request($req);
ok( $res->is_success, 'Successful request' );
is( $res->content '{"user":"sawyer_x"}', 'Empty response back' );
$jar->extract_cookies($res);
ok( ! $jar->as_string, 'All cookies deleted' );
};
done_testing();</pre>
<p>Here we create a cookie jar, make sure all our requests and responses work
with it, and we can even check for existing cookies, as well as cookies
that were deleted by the response, since <a href="https://metacpan.org/module/HTTP::Cookies">HTTP::Cookies</a> will understand
a delete request (by setting an older time) and delete it.</p>
<p>You will notice that we use a full domain. This is because
<a href="https://metacpan.org/module/HTTP::Cookies">HTTP::Cookies</a> needs the entire URL (including the scheme part) to make
the cookies work.</p>
<h2><a name="accessing_the_configuration_file"></a>Accessing the configuration file</h2>
<p>By importing <a href="https://metacpan.org/module/Dancer2">Dancer2</a> in your command line scripts, you have full
access to the configuration using the imported keywords:</p>
<pre class="prettyprint">use strict;
use warnings;
use Test::More;
use Plack::Test;
use HTTP::Request::Common;
use MyApp;
use Dancer2;
my $appname = config->{'appname'};
diag "Testing $appname";
# ...</pre>
<p>In this example we use the <code>config</code> keyword to access the
configuration. That's all you have to do if you want to access it as part
of your test.</p>
<h2><a name="testing_environment"></a>Testing environment</h2>
<p>You can also set your own environment file for testing, such as
<code>environments/testing.yml</code> and then load it in your test script:</p>
<pre class="prettyprint">BEGIN { $ENV{'DANCER_ENV'} = 'testing' }
# ...</pre>
<p>Now you can insert your own configurations.</p>
<h2><a name="setup_method"></a>Setup method</h2>
<p>My current favorite method for dynamically handling onfigurations in my
<a href="https://metacpan.org/module/Dancer2">Dancer2</a> applications is by having a <code>setup</code> method. When loading my
applications in my handlers, I call that method, and it then checks the
configuration for variables.</p>
<p>This allows me to tweak and change the configuration before calling the
<code>setup</code> method, thus letting me bootstrap my own changes, such as in
testing scripts.</p>
<p>A separate article about this trick just might appear on the Advent
Calendar this year.</p>
<h2><a name="where_are_the_test_helpers"></a>Where are the test helpers?</h2>
<p>Both Dancer 1 and 2 have <a href="https://metacpan.org/module/Dancer::Test">Dancer::Test</a> and <a href="https://metacpan.org/module/Dancer2::Test">Dancer2::Test</a>, respectively,
but in <a href="https://metacpan.org/module/Dancer2">Dancer2</a> it is currently not recommended.</p>
<p>The reason is that, because they weren't written with PSGI in mind, they
are bending over backwards in order to fake the request, run it against
a fake dispatcher, and then return a fake response.</p>
<p>At the end of the day, it isn't only buggy and took a lot of our time and
efforts into maintaining it, but it is also counter-intuitive.</p>
<p>We might reinstate it later, once we've redesigned it to simply be a helper
layer on top of <a href="https://metacpan.org/module/Plack::Test">Plack::Test</a>.</p>
<p>For now, we suggest to avoid it and go directly for <a href="https://metacpan.org/module/Plack::Test">Plack::Test</a>.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Writing tests is a lot of fun and they help us make sure our applications
work the way we want them to work. They help flesh out features, APIs,
and maintain their correctness throughout changes, big and small.</p>
<p>Writing tests for web application used to be difficult, but now, with the
magic of <a href="https://metacpan.org/module/PSGI">PSGI</a>, it is simple and straight-forward.</p>
<p>You can read more about testing in <a href="https://metacpan.org/module/Dancer2::Manual::Testing">Dancer2::Manual::Testing</a>.</p>
<p>Our next article will cover how we write tests ourselves in the <a href="https://metacpan.org/module/Dancer2">Dancer2</a>
core.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Serial Serializer - making API writing easier
http://advent.perldancer.org/2014/11
perlhttp://advent.perldancer.org/2014/11Thu, 11 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="serial_serializer___making_api_writing_easier"></a>Serial Serializer - making API writing easier</h1>
<p>One of Dancer's engines is the <b>serializer</b>, which helps you with writing
APIs.</p>
<p>Serializers essentially do two things:</p>
<ul>
<li><a name="item_Deserialize_incoming_requests"></a><b>Deserialize incoming requests</b>
<p>When a user makes a request with serialized input, the serializer
automatically deserializes it into actual input parameters.</p>
</li>
<li><a name="item_Serialize_outgoing_responses"></a><b>Serialize outgoing responses</b>
<p>When you return a data structure from a route, it will automatically serialize
it for you before returning it to the user.</p>
</li>
</ul>
<h2><a name="configuring"></a>Configuring</h2>
<p>In order to configure a serializer, you just need to pick which format
you want for encoding/decoding (from the available
Serializer namespace - <code>Dancer::Serializer</code> for Dancer 1 and
<code>Dancer2::Serializer</code> for Dancer2) and set it up using the <code>serializer</code>
configuration keyword.</p>
<p>It's recommended to explicitly add it in the actual code instead of the
configuration file so it doesn't apply automatically to every app that
reads the configuration file (unless that's what you want):</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
set serializer => 'JSON'; # Dancer2::Serializer::JSON
...</pre>
<h2><a name="using"></a>Using</h2>
<p>Now that we have a serializer set up, we can just return data structures:</p>
<pre class="prettyprint">get '/' => sub {
return { resources => \%resources };
};</pre>
<p>When we return this data structure, it will automatically be serialized
into JSON. No other code is necessary.</p>
<p>We also now receive requests in JSON:</p>
<pre class="prettyprint">post '/:entity/:id' => sub {
my $entity = param('entity');
my $id = param('id');
# input which was sent serialized
my $user = param('user');
...
};</pre>
<p>We can now make a serialized request:</p>
<pre class="prettyprint">$ curl -X POST http://ourdomain/person/16 -d '{"user":"sawyer_x"}'</pre>
<p>It's all automatic.</p>
<h2><a name="always_or_never"></a>Always or never</h2>
<p>In previous versions of <a href="https://metacpan.org/module/Dancer2">Dancer2</a> (and in <a href="https://metacpan.org/module/Dancer">Dancer</a> 1), serializers were only
used when the data is a reference.</p>
<p>There were some issues with that:</p>
<ul>
<li><a name="item_Unclear_behavior"></a><b>Unclear behavior</b>
<p>You could have mixed routes that return serialized and non-serialized
content, which is a source for confusion and inconsistency.</p>
<p>Now you simply handle this by providing a package that has a serializer
and a package that renders content. You can then separate them to different
mounting points using <a href="https://metacpan.org/module/Plack::Builder">Plack::Builder</a> as explained in a previous article
and showed below.</p>
</li>
<li><a name="item_What_if_the_data_is_a_string_"></a><b>What if the data is a string?</b>
<p>Some serializers actually handle strings. <a href="https://metacpan.org/module/Dancer2::Serializer::CBOR">Dancer2::Serializer::CBOR</a>, for
example, can serialize strings. This previous ref-only behavior would render
those serializers broken - not good.</p>
</li>
</ul>
<p>Instead, now everything is sent to serializers. Bad requests receive
warnings and errors.</p>
<h2><a name="hooks"></a>Hooks</h2>
<p>While we're still working on adding an error hook, you can already hook
into the serializer with a <i>before</i> and <i>after</i>:</p>
<pre class="prettyprint">hook before_serializer => sub {...};
hook after_serializer => sub {...};</pre>
<h2><a name="app_specific_feature"></a>App-specific feature</h2>
<p>Remember that serializers are engines. They affect a Dancer Application,
which means that once you've set a serializer, <b>all</b> routes within that
package will be serialized and deserialized. This is how the feature works.</p>
<p>As suggested above, if you would like to have both, you need to create
another application which will not be serialized.</p>
<p>A common usage for this is an API providing serialized endpoints (and
receiving serialized requests) and providing rendered pages.</p>
<pre class="prettyprint"># MyApp.pm
package MyApp;
use Dancer2;
# another useful feature:
set auto_page => 1;
get '/' => sub { template 'index' => {...} };
# MyApp/API.pm
package MyApp::API;
use Dancer2;
set serializer => 'JSON'; # or any other serializer
get '/' => sub { +{ resources => \%resources, ... } };
# user-specific routes, for example
prefix => '/users' => sub {
get '/view' => sub {...};
get '/view/:id' => sub {...};
put '/add' => sub {...}; # automatically deserialized params
};
...</pre>
<p>Then those will be mounted together for a single app:</p>
<pre class="prettyprint"># handler: app.pl:
use MyApp;
use MyApp::API;
use Plack::Builder;
builder {
mount '/' => MyApp->to_app;
mount '/api' => MyApp::API->to_app;
};</pre>
<p>There ya go!</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Serializers make it much easier to write API interfaces. We recommend using
them in order to save yourself on typing. However, use caution knowing they
will handle all input and all output and affect all routes in a package.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>What's in an appname?
http://advent.perldancer.org/2014/10
perlhttp://advent.perldancer.org/2014/10Wed, 10 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="what_s_in_an_appname"></a>What's in an appname?</h1>
<h2><a name="new_feature_in_dancer2__appname"></a>New feature in Dancer2: appname</h2>
<p>One change we absolutely love is the <code>appname</code> import option, introduced in
<a href="https://metacpan.org/module/Dancer2">Dancer2</a> 0.150000.</p>
<h2><a name="what_s_a_dancer_app_again"></a>What's a Dancer App again?</h2>
<p>It's worth repeating the explanation of what a Dancer2 application is, since
this might confuse a developer with a <a href="https://metacpan.org/module/PSGI">PSGI</a> application.</p>
<p>A Dancer2 App is simply a package containing routes and engines which receives
a request and returns a response. The engines are not mandatory, but might be
a template, a session, a logger, and a serializer.</p>
<p>A PSGI application is a code reference which receives a request as a hash of
environment variables (from a server using a <a href="https://metacpan.org/module/Plack">Plack</a> handler) and returns a
proper PSGI response which could be an array reference or a code reference.</p>
<h2><a name="too_many_apps_"></a>Too many apps!</h2>
<p>As soon as you import <a href="https://metacpan.org/module/Dancer2">Dancer2</a> (by calling <code>use Dancer2</code>), you create a
Dancer2 App. It will use your class name (defined by either the <code>package</code>
function in Perl or the default in Perl: <code>main</code>) to define the Dancer2 App
name. This is how Dancer2 will recognize your application.</p>
<p>This introduces an interesting situation. If you wish to separate your App
to multiple files, you're actually creating multiple applications.</p>
<h2><a name="so_what"></a>So what?</h2>
<p>This means that any engine defined in an application, because the application
is a complete separate scope, will not be available to a different application:</p>
<pre class="prettyprint">package MyApp::User {
use Dancer2;
set serializer => 'JSON';
get '/view' => sub {...};
}
package MyApp::User::Edit {
use Dancer2;
get '/edit' => sub {...};
}</pre>
<p>These are two different Dancer2 Apps. They have different scopes, contexts,
and thus different engines. While <code>MyApp::User</code> has a serializer (the <a href="https://metacpan.org/module/JSON">JSON</a>
one) defined, <code>MyApp::User::Edit</code> will not have that configuration.</p>
<p>If you want the path <code>/edit</code> to have a serializer also, you will need to
define one for <code>MyApp::User::Edit</code>. This is not just tedious, but when you
mix this with the <code>to_app</code> method (described in the previous article, you
have a problem:</p>
<pre class="prettyprint">use MyApp::User;
use MyApp::User::Edit;
use Plack::Builder;
builder {
mount '/' => MyApp::User->to_app;
# what about MyApp::User::Edit ???
};</pre>
<p>If <code>/</code> is taken by <code>MyApp::User</code>, where do we put <code>MyApp::User::Edit</code>?</p>
<p>We don't actually wish <code>MyApp::User::Edit</code> to be another application, we just
want it to be a comfortable extension to the regular app, providing additional
routes that are part of the same already-existing application.</p>
<p>While you might think loading <code>MyApp::User::Edit</code> within <code>MyApp::User</code> will
help to just extend it, that is not the case. It will still fail.</p>
<p><code>appname</code> to the rescue!</p>
<h2><a name="appname_saves_the_day"></a>appname saves the day</h2>
<p>By using the import option <code>appname</code>, we can ask Dancer2 to extend an App
without creating a new one:</p>
<pre class="prettyprint">package MyApp::User {
use Dancer2;
set serializer => 'JSON';
get '/view' => sub {...};
}
package MyApp::User::Edit {
use Dancer2 appname => 'MyApp::User'; # extending MyApp::User
get '/edit' => sub {...};
}</pre>
<p>Now, by using <code>appname</code> when importing, we can ask this App to simply extend
an existing one (or one will be created if it does not exist yet) and add
the routing there.</p>
<p>The serializer will be available, it will have the same configuration, and it
will even represent all of the routes with the same internal application
object.</p>
<pre class="prettyprint"># app.pl
use MyApp::User;
use MyApp::User::Edit;
# single application composed of routes provided in multiple files
MyApp::User->to_app;</pre>
<p>Usually we would load classes that contain additional routes inside the
original class they extend:</p>
<pre class="prettyprint">package MyApp::User {
use Dancer2;
use MyApp::User::Edit;
set serializer => 'JSON';
...
}</pre>
<p>This way we only need to load one when we create an app:</p>
<pre class="prettyprint"># app.pl:
use MyApp::User;
MyApp::User->to_app;</pre>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>The import option <code>appname</code> allows you to seamlessly extend Dancer2 Apps
without creating unnecessary additional applications or repeat any definitions.</p>
<p>This allows you to spread your application routes across multiple files and
allow ease of mind when developing it, and accommodate multiple developers
working on the same codebase.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>New feature in Dancer2: to_app
http://advent.perldancer.org/2014/9
perlhttp://advent.perldancer.org/2014/9Tue, 9 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="new_feature_in_dancer2__to_app"></a>New feature in Dancer2: to_app</h1>
<p><a href="https://metacpan.org/module/Dancer2">Dancer2</a> 0.151000 has made a major change to the dispatching mechanism and
provided a new method: <code>to_app</code>. What was the change, why was this keyword
introduced, and why should we use it now?</p>
<h2><a name="the_way_things_were"></a>The way things were</h2>
<p>The original dispatching mechanism in Dancer2 would take all of your Dancer2
applications and wrap them with a loop that tries to match their routes. Once
you know that a <i>Dancer App</i> is basically a unit of routes with its own set
of engines (such as a template, a session storage, a logger, and a serializer -
not all required), you might begin to see a problem here.</p>
<p>If you have two applications (meaning two packages that have <code>use Dancer2</code> in
them) called <code>MyApp::A</code> and <code>MyApp::B</code>, and you call the <code>dance</code> keyword
to create a full fledged PSGI application from them, Dancer will try to match
a request against each one. It will start with <code>MyApp::A</code> and then <code>MyApp::B</code>.</p>
<p><i>"Is it always in this order?"</i>, you might ask. Actually, it isn't. Since it
is internally stored in an array (which is at least deterministic, right?), it
is actually checked in the order in which you loaded them into memory.</p>
<p>If your handler is:</p>
<pre class="prettyprint">use MyApp::B;
use MyApp::A;
use Dancer2;
dance;</pre>
<p>It will now check <code>MyApp::B</code> first and <code>MyApp::A</code> last.</p>
<p>In fact, it will check <code>MyApp::B</code> first, <code>MyApp::A</code> second, and the last
will be whatever package this snippet of code you saw is in - in case it
has any routes configured in it before <code>dance</code> was called.</p>
<h2><a name="why_is_this_bad"></a>Why is this bad?</h2>
<p>So you might be wondering, <i>"Okay, there's an order issue here, but why
should I care? Eventually it reaches my route and works fine."</i></p>
<p>You are absolutely right - in most cases. However, if both applications have
the same route defined, you won't necessarily know which route was actually
hit.</p>
<p>If you're preloading applications into memory (which is a good idea in large
infrastructures), your resulting application might hit someone else's route
instead.</p>
<p>If you're using the <b>AutoPage</b> feature, you might snag on a different app's
template. If one app has a <b>Serializer</b> defined, you might return serialized
output. If different apps have a different <b>Session</b> engine, that's even
worse. That's tantamount to a security risk - although we try to minimize that
risk internally by moving session objects around so you don't hit a mistaken
session.</p>
<h2><a name="what_can_we_do"></a>What can we do?</h2>
<p>The first change we made, back in Dancer2 0.150000, was to call the
<code>psgi_app</code> keyword with specific application names, either by class name or
by a regular expression. This allowed you to create PSGI applications from
specific Dancer Apps:</p>
<pre class="prettyprint"># preload everything
use MyApp::A;
use MyApp::B;
use MyApp::C;
use MyApp::D;
use MyApp::E;
# an app for A, B, C
my $abc_app = Dancer2->psgi_app([ qr{^MyApp::[ABC]$} ]);
# an app for D, E
my $d_app = Dancer2->psgi_app([ 'MyApp::D', 'MyApp::E' ]);</pre>
<p>This allows us to load into memory all the applications we have and then
create a PSGI application from only some of them.</p>
<p>Here is another example which also joins multiple apps into a single,
bigger PSGI app with <a href="https://metacpan.org/module/Plack::Builder">Plack::Builder</a>:</p>
<pre class="prettyprint">use MyApp::A;
use MyApp::B;
use MyApp::C;
use Plack::Builder;
builder {
mount '/' => Dancer2->psgi_app(['MyApp::A']);
mount '/special' => Dancer2->psgi_app([ qr{^MyApp::[BC]$} ]);
};</pre>
<p>This was a major improvement, but it still didn't address the core problem.</p>
<h2><a name="fine__i_ll_bite__what_was_the_core_problem"></a>Fine. I'll bite. What was the core problem?</h2>
<p>I'm glad you asked!</p>
<p>The code problem was that the dispatching was the duty of the core dispatcher
object (an instance of <a href="https://metacpan.org/module/Dancer2::Core::Dispatcher">Dancer2::Core::Dispatcher</a>) instead of the app object
itself (<a href="https://metacpan.org/module/Dancer2::Core::App">Dancer2::Core::App</a>). Since the routing should have been done in the
app object (the lowest context for engines and routes), it made sense to move
it there instead of the dispatcher object.</p>
<p>We've done so in Dancer2 0.151000, a version later.</p>
<p>While retaining the old behavior of the <code>psgi_app</code> keyword, we introduced
one major addition: the <code>to_app</code> class method.</p>
<h2><a name="to_app_or_not_to_app"></a>to_app or not to_app</h2>
<p>While perhaps not the same question Shakespeare asked, it is a noble one
just the same.</p>
<p>The <code>to_app</code> method creates a PSGI app from a single application - not from
all of your applications or a PSGI app that is restricted to specific ones.</p>
<p>This means you can now treat a Dancer2 App as its own unit that can be
composed into any path you like.</p>
<p>The following:</p>
<pre class="prettyprint">MyApp->to_app;</pre>
<p>gives the same behavior to the user as:</p>
<pre class="prettyprint">Dancer2->psgi_app(['MyApp']);</pre>
<p>except it does it using quite a few workarounds.</p>
<p>Instead of using the awkward <code>Dancer2->psgi_app()</code>, which
provides the same behavior as <code>dance()</code>, you could use <code>to_app</code>. This
won't require calling <code>use Dancer2</code> in your handler, since it's a method
on your Dancer2 application class.</p>
<p>When you have multiple Dancer2 applications, you can compose them together
using either <a href="https://metacpan.org/module/Plack::App::URLMap">Plack::App::URLMap</a> or the wrapper syntax for it available in
<a href="https://metacpan.org/module/Plack::Builder">Plack::Builder</a>:</p>
<pre class="prettyprint">use MyApp::Main;
use MyApp::Admin;
builder {
mount '/' => MyApp::Main->to_app;
mount '/admin' => MyApp::Admin->to_app;
};</pre>
<p>The effect of the mounting is that these applications will be completely
separate and <a href="https://metacpan.org/module/Plack::Builder">Plack::Builder</a> will assure only the appropriate application
handles a given request.</p>
<p>Instead of creating a loop around all of them, you provide each app with its
own dispatching mechanism, in charge only for the routes defined inside it.</p>
<p>Another effect of mounting is that the mounting point (<code>/admin</code>, for example)
is stripped from the path the application needs to match. This means that
<code>MyApp::Admin</code> doesn't need to define <code>/admin/view</code>, but just <code>/view</code>.</p>
<p>This has become such a useful and important feature that if you try to call
<code>psgi_app</code> on an application (instead of on <code>Dancer2</code> or
<code>Dancer2->runner</code>, it will effectively call <code>to_app</code> underneath.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>In short, yes. We <b>do</b> want <code>to_app</code>. :)</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Sweetening the test suite
http://advent.perldancer.org/2014/8
perlhttp://advent.perldancer.org/2014/8Mon, 8 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="sweetening_the_test_suite"></a>Sweetening the test suite</h1>
<p>The testing suite of a project is an important component, allowing users and
developers to maintain trust in the code. Having an organized testing suite
makes it easier for developers to add new tests, improve existing tests, and
make sure tests are evenly covering the variety of code from all of its
angles, as well as making it easier for contributors to help out.</p>
<h2><a name="the_sweet_suite"></a>The sweet suite</h2>
<p>While mayhem ruled the testing suite of Dancer (both version 1 and 2), we've
recently started rearranging it in order to handle the various situations our
code works under.</p>
<p>Here's the new structure:</p>
<h3><a name="t_classes_"></a>t/classes/</h3>
<p>The main component of the testing suite are the classes. In <a href="https://metacpan.org/module/Dancer2">Dancer2</a> all the
DSL implementation is built on top of core classes. This allows us to
decouple the keywords the user uses and their implementation.</p>
<p>Under the <i>t/classes/</i> we run tests for classes only. This should not run web
requests, understand the web environment, or anything of the sort. Some
exceptions may apply, but we try to minimize those.</p>
<p>Each class has a directory for itself, allowing you to quick find it, and add
tests to it. Each method gets its own test file. We test roles as well, of
course. In each directory we can provide static files fo test various
scenarios.</p>
<h3><a name="t_dsl_"></a>t/dsl/</h3>
<p>The user-visible interface of the Dancer web framework is the DSL, which are
those keywords we use to define routing.</p>
<p>The DSL is tested under the <i>t/dsl/</i> directory. Inside it each DSL keyword
has its own file. Keywords requiring more than a single test, or requiring
static files (such as sample configuration files), receive their own
directory.</p>
<p>We're still porting the old DSL keywords into clean tests inside the
<i>t/dsl/</i> directory, which means this directory is still relatively small
and most of the DSL tests are strewn across the general <i>t/</i> directory.</p>
<p>We wouldn't say no to any help offered. :)</p>
<h3><a name="t_issues_"></a>t/issues/</h3>
<p>Regression tests offer a test which isn't covered by the above described
categories. We use regression tests to check specific situations, rather than
code paths.</p>
<p>Since these situations arise in tickets (and tickets can always be opened
for them if not), we created a directory holding all of these tests, sorted
by the tracker and the ticket ID in that tracker.</p>
<p>Often times a good way to handle an issue is to provide a test, which
can then allow verifying it was fixed.</p>
<p>For example, we have <i>t/issues/gh-723.t</i> to make sure that scenario doesn't
pop up again as a bug.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Nowadays when we want to play with tests, we already know where they go and
how to write them. Now you do too, which makes it possible for you to write up
some tests when providing a fix or a feature, or when you just want to improve
the testing coverage.</p>
<p>Consistency in the test suite is absolutely vital in order to
continually improve the testing coverage and make sense of the testing code.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Doing an API Mashup with Dancer
http://advent.perldancer.org/2014/7
perlhttp://advent.perldancer.org/2014/7Sun, 7 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="doing_an_api_mashup_with_dancer"></a>Doing an API Mashup with Dancer</h1>
<p>I was delighted to receive a Twitter message from Su-Shee on an article
about mashing up an API call with <a href="http://www.sinatrarb.com/">Sinatra</a>:</p>
<blockquote class="twitter-tweet" lang="en"><p>.<a href="https://twitter.com/PerlSawyer">@PerlSawyer</a> tiny total beginner's <a href="https://twitter.com/hashtag/sinatra?src=hash">#sinatra</a> example, should be blatantly copied for <a href="https://twitter.com/hashtag/dancer?src=hash">#dancer</a>... <a href="https://t.co/SlSia0f92a">https://t.co/SlSia0f92a</a> "learn how to API" :)</p>— Su-Shee (@sheeshee) <a href="https://twitter.com/sheeshee/status/541175744358268928">December 6, 2014</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>You might wonder how a version of it would look like in Dancer. Shouldn't
be a problem. Let's have a go at it!</p>
<h2><a name="prior_work"></a>Prior work</h2>
<p>If you haven't had the time or inclination to read the aforementioned
article (which we actually recommend), here is a brief description of our
task.</p>
<p>We want to create an app that makes a request to a weather API and then
displays it dynamically in a web page.</p>
<h2><a name="to_everything_a_start"></a>To everything a start</h2>
<p>Setting up the application was relatively quick. Open up your favorite
editor on a new file. Let's call it <i>mashup.pl</i>:</p>
<p>Other than <a href="https://metacpan.org/module/Dancer2">Dancer2</a> for defining routes, we will use <a href="https://metacpan.org/module/HTTP::Tiny">HTTP::Tiny</a> to
make the weather API request, <a href="https://metacpan.org/module/JSON">JSON</a> to decode it from JSON format, and
finally <a href="https://metacpan.org/module/File::Spec">File::Spec</a> to provide a fully-qualified path to our template
engine. That last bit will be explained later on.</p>
<pre class="prettyprint">use JSON;
use Dancer2;
use HTTP::Tiny;
use File::Spec;</pre>
<h2><a name="configuration"></a>Configuration</h2>
<p>Now we set up some variables for our web application. We will use the
excellent <a href="https://metacpan.org/module/Template">Template::Toolkit</a> template system. It is simple and
easy to work with.</p>
<p>Dancer searches for our templates in our views directory, which defaults
to <i>views</i> directory in our current directory. Since we want to put our
template in our current directory, we will configure that. However,
<i>Template::Toolkit</i> does not want us to provide a relative path without
configuring it to allow it. This is a security issue. So, we're using
<a href="https://metacpan.org/module/File::Spec">File::Spec</a> to create a full path to where we are.</p>
<p>We also unset the default layout, so Dancer won't try to wrap our template
with another one. This is a feature in Dancer to allow you to wrap your
templates with a layout when your templating system doesn't support it.
Since we're not using a layout here, we don't need it.</p>
<pre class="prettyprint">set template => 'template_toolkit'; # set template engine
set layout => undef; # disable layout
set views => File::Spec->rel2abs('.'); # full path to views</pre>
<p>A lot of explanation and only three lines of code. :)</p>
<p>Now, we define our URL:</p>
<pre class="prettyprint">my $url = 'http://api.openweathermap.org/data/2.5/weather?id=5110629&units=imperial';</pre>
<h2><a name="route___the_gist_of_it"></a>Route - the gist of it</h2>
<p>The main component is our web route. We will define a main route which,
upon a request, will fetch the information from the weather API, decode it,
and then display it to the user.</p>
<p>Route definition:</p>
<pre class="prettyprint">get '/' => sub {
...
};</pre>
<p>Editing the stub of route dispatching code, we start by making the
request and decoding it:</p>
<pre class="prettyprint"># fetch data
my $res = HTTP::Tiny->new->get($url);
# decode request
my $data = decode_json $res->{'content'};</pre>
<p>The data is not just a flat hash. It's a deep structure. To make this post
simpler, we will filter it for only the simple keys in the retrieved data:</p>
<pre class="prettyprint">my $metrics = { map +(
ref $data->{$_} ? () : ( $_ => $data->{$_} )
), keys %{$data} };</pre>
<p>All that is left now is to render it:</p>
<pre class="prettyprint">template index => { metrics => $metrics };</pre>
<p>Oh, and to make this into a runnable-application, we add the magic word:</p>
<pre class="prettyprint">dance;</pre>
<h2><a name="and_the_template"></a>And the template</h2>
<p>We can't forget about the HTML code of course. The following is our
<i>index.tt</i> template file:</p>
<pre class="prettyprint"><table>
<th>The Weather in Buffalo, NY, USA</th>
<tr>
<td>
[% FOREACH metric IN metrics.keys %]
<tr><td>[% metric %]</td><td>[% metrics.$metric %]</td></tr>
[% END %]
</td>
</tr>
</table>
<hr noshade>
Powered by the <a href = 'http://openweathermap.org/' target = _new>Open W
eather Map API</a></pre>
<p>Et Voila!</p>
<h2><a name="all_together_now"></a>All together now</h2>
<p>Here is our complete app:</p>
<pre class="prettyprint">use JSON;
use Dancer2;
use HTTP::Tiny;
use File::Spec;
set template => 'template_toolkit';
set layout => undef;
set views => File::Spec->rel2abs('.');
my $url = 'http://api.openweathermap.org/data/2.5/weather?id=5110629&units=imperial';
get '/' => sub {
my $res = HTTP::Tiny->new->get($url);
my $data = decode_json $res->{'content'};
my $metrics = { map +(
ref $data->{$_} ? () : ( $_ => $data->{$_} )
), keys %{$data} };
template index => { metrics => $metrics };
};
dance;</pre>
<p>And the result we have at the end:</p>
<table>
<th>The Weather in Buffalo, NY, USA</th>
<tr>
<td>
<tr><td>id</td><td>5110629</td></tr>
<tr><td>cod</td><td>200</td></tr>
<tr><td>name</td><td>Buffalo</td></tr>
<tr><td>base</td><td>cmc stations</td></tr>
<tr><td>dt</td><td>1417885200</td></tr>
</td>
</tr>
</table>
<hr noshade>
Powered by the <a href = 'http://openweathermap.org/' target = _new>Open Weather Map API</a>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Many of the odder configuration options were actually due to writing an
application outside the defaults of a normal production-ready application.</p>
<p>If we had a <i>views</i> directory, we wouldn't need <a href="https://metacpan.org/module/File::Spec">File::Spec</a> and
to configure the <code>views</code>. If we had used a layout, which we would normally
use, we wouldn't need to disable the layout using the <code>layout</code>
option. If we tried to account for all data returned, we would also write
a template that supports a deeper structure, or dumped it to HTML from its
hash representation, which would probably had been easier.</p>
<p>At the end, the production code would share all of these comments and end
up both smaller and simpler. Of course, our production code would check
for errors on fetching the data and decoding it, which we have conveniently
ignored. :)</p>
<p>One clear difference between our implementation and the <i>Sinatra</i> one is
we don't actually stick any HTML in the code itself. There is no need. We
simply throw it to the templating engine.</p>
<p>With light web frameworks writing your application is usually as
straight-forward and simple as it seems in our head.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Static noise - Static file serving in Dancer2
http://advent.perldancer.org/2014/6
perlhttp://advent.perldancer.org/2014/6Sat, 6 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="static_noise___static_file_serving_in_dancer2"></a>Static noise - Static file serving in Dancer2</h1>
<p>All too often beginners would stumble over the behavior of static file
serving in Dancer2. The idea made sense on paper but somehow, when you
put it in practical terms, it wasn't just a hurdle but a real pain to
constantly headbutt without realizing, <i>"damn it, that again!"</i></p>
<p>The good news is we fixed it. The bad news is you will have to read this
article to understand what we're talking about. The treat is we will explain
how it was fixed after we explain what was wrong.</p>
<h2><a name="ex_static"></a>Ex-static</h2>
<p>The logic for request serving in Dancer 1 is simple. It consists of the
following steps run in order:</p>
<ul>
<li><a name="item_Try_to_render_a_static_file_from__code_public___code_"></a><b>Try to render a static file from <code>public/</code></b>
</li>
<li><a name="item_Try_to_render_an_action___a_user_s_route"></a><b>Try to render an action - a user's route</b>
</li>
<li><a name="item_Try_to_render_an_AutoPage___a_user_s_template"></a><b>Try to render an AutoPage - a user's template</b>
</li>
<li><a name="item_Give_up_and_render_a_404_page"></a><b>Give up and render a 404 page</b>
</li>
</ul>
<p>In <a href="https://metacpan.org/module/Dancer2">Dancer2</a> these items were broken down into composable units known as
handlers. <a href="https://metacpan.org/module/Dancer2::Handler::File">Dancer2::Handler::File</a> serves static files (which
the DSL keyword <code>send_file</code> uses internally) and
<a href="https://metacpan.org/module/Dancer2::Handler::AutoPage">Dancer2::Handler::AutoPage</a> renders template files.</p>
<p>These handlers were, when configured to be used (or according to the
defaults), merged into an application as regular routes. To make sure they
don't cause any confusion, they were merged at the very end. Oops. Strike
one!</p>
<p>The following order was created:</p>
<ul>
<li><a name="item_Try_to_match_a_user_route"></a><b>Try to match a user route</b>
</li>
<li><a name="item_Try_to_match_a_static_file_route__Handler__File_"></a><b>Try to match a static file route (Handler::File)</b>
</li>
<li><a name="item_Try_to_match_a_rendered_template__Handler__AutoPage_"></a><b>Try to match a rendered template (Handler::AutoPage)</b>
</li>
<li><a name="item_Give_up_and_render_a_404_page"></a><b>Give up and render a 404 page</b>
</li>
</ul>
<p>While it seems reasonable for user-defined routes to trump static resources
and templates, people were not expecting it to happen, which led to a few
peculiar situations.</p>
<h2><a name="problem_1__greed_is_not_good"></a>Problem 1: Greed is NOT good</h2>
<p>In order for these routes to accept <i>any</i> input, they use a greedy
<b>megasplat</b> route, which captures everything:</p>
<pre class="prettyprint">get '/**' => sub {
# I SEE ALL ROUTES
# (as long as they are a GET request)
};</pre>
<p>(Users can define these routes as well, of course.)</p>
<p>The first manifestation of the reshuffling in order of execution occurred
when users defined greedy <b>megasplat</b> routes which accidentally captured
all static requests as well:</p>
<pre class="prettyprint">get '/**' => sub {
# handle what I think is a user request
# but can also be a static file request
};</pre>
<p>Now users had to account for static files being asked of them. Ouch. This
is actually the small problem.</p>
<h2><a name="problem_2__a_hook_to_kill"></a>Problem 2: A hook to kill</h2>
<p>Remember hooks? Sure you do. Every route can have hooks. Amongst available
hooks there are the <b>before</b> and <b>after</b> hooks which control the execution
sequence of a matched route, allowing you to call code before and after it is
executed, respectively.</p>
<p>How does that come into play? Since the <b>File</b> and <b>AutoPage</b> handlers
create regular routes (just like a user might), the <b>before</b> and <b>after</b>
hooks actually apply to them.</p>
<p>What?</p>
<p>Yes! This meant that, for example, your <b>before</b> route hooks were called for
static files. If they contained a security check (for which many users use
them), you might accidentally prevent a file from being rendered. Strike two!</p>
<p><i>"You can't see the lacking access picture because you lack access!"</i></p>
<h2><a name="plack_strikes_back"></a>Plack strikes back</h2>
<p>Before we hit a <i>strike three</i> we decided to fix this. Since we're
depending on <a href="https://metacpan.org/module/Plack">Plack</a> and the associated technology to help resolve so many
issues, we looked there.</p>
<p>One wonderful part of Plack is the middlewares. One specific middleware
that came to our rescue was <a href="https://metacpan.org/module/Plack::Middleware::Static">Plack::Middleware::Static</a>. It allow us to
render static files from the <code>public/</code> directory before it actually
reaches our application and Dancer2 dispatching code at all. Wait, what?</p>
<p>The Plack middleware wraps the Dancer2 code and checks for static files on
each request before it sends it off to Dancer2. If it can find a file that
matches the request, it will serve it directly instead of passing it
onwards.</p>
<p>This means we're back to a proper static file serving behavior. They are
now served properly before the app and the hooks do not apply to them.</p>
<p>We still kept the <b>File</b> handler to provide <code>send_file</code>, but it
is no longer in charge of automatically serving static files.</p>
<p>The <b>AutoPage</b> handler is kept as is because hooks make sense in rendering
templates. You might want to use the <b>before_template</b> hook in order
to provide default variables that will be available in every template
rendering (including automatic ones served by <b>AutoPage</b>) - which is
something you will not have with static content.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Wonderful work by
<a href="https://metacpan.org/author/RUSSELLJ">Russell @veryrusty Jenkins</a>
solving this thorn in Dancer2 and providing consistent behavior that
makes sense.</p>
<p>If you meet him, offer him a drink. He's Australian so he'll take it. :)</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Packing the Fat
http://advent.perldancer.org/2014/5
perlhttp://advent.perldancer.org/2014/5Fri, 5 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="packing_the_fat"></a>Packing the Fat</h1>
<p>After speaking of one way to handle dependencies, it's time to talk about
another.</p>
<p>One promise we've made with <a href="https://metacpan.org/module/Dancer2">Dancer2</a> is it will always be <i>fatpackable</i>,
but only a few people actually know what this means and why it's
important.</p>
<p>If you keep on reading, you're going to join that group of people.</p>
<h2><a name="fatpacker"></a>FatPacker</h2>
<p>One of the reasons people worry about dependencies is not being able to
install them. Of course you could use <a href="https://metacpan.org/module/local::lib">local::lib</a> or <a href="https://metacpan.org/module/carton">carton</a> to
install them locally, but another mechanism available is <a href="https://metacpan.org/module/App::FatPacker">App::FatPacker</a>.</p>
<p><a href="https://metacpan.org/module/App::FatPacker">App::FatPacker</a> (using its command line interface, <a href="https://metacpan.org/module/fatpack">fatpack</a>) packs
dependencies into a single file (hence the name), allowing you to carry
a single file instead of a directory tree.</p>
<p>If you're interested in understanding <a href="https://metacpan.org/module/App::FatPacker">App::FatPacker</a>, I have written
<a href="http://www.perladvent.org/2012/2012-12-14.html">an article</a> describing
it, how it works, and how to use it.</p>
<h2><a name="fatpacking_dancer2_applications"></a>FatPacking Dancer2 applications</h2>
<p>By saying <a href="https://metacpan.org/module/Dancer2">Dancer2</a> is fatpackable, we mean that we make sure the
Dancer2 can be fatpacked. We do this by requiring by default only
pure-Perl modules. We allow you to optionally install XS modules
to improve speed, but Dancer2 will work just fine without them.</p>
<p>This means that as long as your application is also pure-Perl, you could
create a single file with your application and all of Dancer2 in it.</p>
<p>Let's take a look at an example.</p>
<p>Assuming we have an application in <i>lib/MyApp.pm</i>:</p>
<pre class="prettyprint">package MyApp;
use Dancer2;
get '/' => sub {'OK'};
1;</pre>
<p>And we have a handler in <i>bin/app.pl</i>:</p>
<pre class="prettyprint">use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyApp;
MyApp->to_app;</pre>
<p>To fatpack it, we will begin by tracing the script:</p>
<pre class="prettyprint">$ fatpack trace bin/app.pl</pre>
<p>This creates a <i>fatpacker.trace</i> file. From this we create the packlists:</p>
<pre class="prettyprint">$ fatpack packlists-for `cat fatpacker.trace` > packlists</pre>
<p>The packlists are stored in a file called, surprisingly, <i>packlists</i>.</p>
<p>Now we create the tree using the following command:</p>
<pre class="prettyprint">$ fatpack tree `cat packlists`</pre>
<p>The tree is created under the directory <i>fatlib</i>.</p>
<p>Now that we have the tree, we simply need to pack it all together. While
this will create a file containing the dependency tree, we also want to
add our script to it, so we'll do it all in one command:</p>
<pre class="prettyprint">$ (fatpack file; cat bin/app.pl) > myapp.pl</pre>
<p>This creates a file called <i>myapp.pl</i> with everything in it. But before
we can run it, we need to account for one small detail. Dancer2
is using <a href="https://metacpan.org/module/MIME::Types">MIME::Types</a> which has a database of all MIME types and helps
translate those. The small database file containing all of these types is
a binary and therefore cannot be fatpacked. We need to copy it to
the current directory so our script can find it.</p>
<pre class="prettyprint">$ cp fatlib/MIME/types.db .</pre>
<p>Now we can use the file just like any other <a href="https://metacpan.org/module/PSGI">PSGI</a> application file:</p>
<pre class="prettyprint">$ plackup myapp.pl</pre>
<p>While we're using <code>plackup</code> here, it's just an example of a server that
will read this. You would usually configure this in your web server as
a PSGI application script.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p><a href="https://metacpan.org/module/Dancer2">Dancer2</a> aims to allow you to package your apps in any number of ways
and <a href="https://metacpan.org/module/App::FatPacker">App::FatPacker</a> is a very useful packaging mechanism we aim to
continually support.</p>
<p>You can now easily pack everyting and send your
co-worker/colleague/enemy a single file that has everything in it,
all dependencies bundled in.</p>
<p>Next time someone says <i>"But I can't install anything"</i>, throw your
packed Dancer web application at them!</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Your website in a carton box
http://advent.perldancer.org/2014/4
perlhttp://advent.perldancer.org/2014/4Thu, 4 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="your_website_in_a_carton_box"></a>Your website in a carton box</h1>
<p>My new favorite way to package <a href="https://metacpan.org/module/Dancer2">Dancer2</a> applications is <a href="https://metacpan.org/module/Carton">Carton</a>.
You setup a single file, type a command or two, and you're done. Here's how
it works and how you set it up yourself.</p>
<h2><a name="what_carton_does"></a>What Carton does?</h2>
<p><a href="https://metacpan.org/module/Carton">Carton</a> sets up a local copy of your project prerequisites. You only need
to define them in a file and ask Carton to download all of them and set them
up.</p>
<p>When you want to deploy your app, you just carry the git clone and ask
Carton to set up the environment again and you will then be able to run it.</p>
<p>The benefit is multi-fold:</p>
<ul>
<li><a name="item_Local_directory_copy"></a><b>Local directory copy</b>
<p>By putting all the dependencies in a local directory, you can make sure
they aren't updated by someone else by accident and their versions locked
to the version you picked.</p>
</li>
<li><a name="item_Sync_versions"></a><b>Sync versions</b>
<p>Deciding which versions of the dependent modules your project needs allows
you to sync this with other developers as well. Now you're all using
the same version and they don't change unless you want update the versions
you want. When updated everyone again uses the same new version of
everything.</p>
</li>
<li><a name="item_Carry_only_the_requirement__not_bundled_modules"></a><b>Carry only the requirement, not bundled modules</b>
<p>Instead of bundling the modules, you only actually bundle the requirements.
Carton builds them for you when you need it.</p>
</li>
</ul>
<h2><a name="setting_it_up"></a>Setting it up</h2>
<p>First thing we do is set up a new app:</p>
<pre class="prettyprint">$ dancer2 -a MyApp
...</pre>
<p>Then we delete the files we don't care about:</p>
<pre class="prettyprint">$ rm -f Makefile.PL MANIFEST MANIFEST.SKIP</pre>
<p>Now let's create a Git repo:</p>
<pre class="prettyprint">$ git init && git add . && git commit -m "initial commit"</pre>
<p>Let's add a requirement using the <a href="https://metacpan.org/module/cpanfile">cpanfile</a> format:</p>
<pre class="prettyprint">$ cat > cpanfile
requires 'Dancer2' => 0.155000;
requires 'Template' => 0;
recommends 'URL::Encode::XS' => 0;
recommends 'CGI::Deurl::XS' => 0;
recommends 'HTTP::Parser::XS' => 0;</pre>
<p>We can now ask Carton to set it up:</p>
<pre class="prettyprint">$ carton install
Installing modules using [...]
Successfully installed [...]
...
Complete! Modules were install into [...]/local</pre>
<p>Now we have two files: <i>cpanfile</i> and <i>cpanfile.snapshot</i>. We add both of
them to our Git repository and we make sure we don't accidentally add the
<i>local/</i> directory Carton created which holds the modules it installed:</p>
<pre class="prettyprint">$ echo local/ >> .gitignore
$ git add .gitignore cpanfile cpanfile.snapshot
$ git commit -m "Start using carton"</pre>
<p>When we want to update the versions on the production machine, we simply
call:</p>
<pre class="prettyprint">$ carton install --deployment</pre>
<p>By using <code>--deployment</code> we make sure we only install the modules we have in
our <i>cpanfile.snapshot</i> file and do not fallback to querying the CPAN.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Setting up <a href="https://metacpan.org/module/Carton">Carton</a> takes two minutes and allows us to provide specific
requirements for our applications and a mechanism to install them on a
production machine while ensuring it will create a local copy of everything.</p>
<p>We no longer care about the system module versions and we can maintain
multiple versions of each module used in each separate application. If a
certain application doesn't need to update a module, it just doesn't have to,
and at the same time doesn't prevent another application from updating its
own modules.</p>
<p>Try it out, you'll love it!</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Migrating to Dancer2
http://advent.perldancer.org/2014/3
perlhttp://advent.perldancer.org/2014/3Wed, 3 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="migrating_to_dancer2"></a>Migrating to Dancer2</h1>
<p>A question we often get asked when we promote <a href="https://metacpan.org/module/Dancer2">Dancer2</a> is <i>"How do I migrate
my code to Dancer2?"</i></p>
<p>There had been some changes between the versions - big enough to require an
entirely new namespace. What were they? How do we migrate?</p>
<h2><a name="changing_the_namespace"></a>Changing the namespace</h2>
<p>The reason we changed the namespace wasn't really due much to the change a
user will necessarily see, but more due to the incredible difference in core
architecture, and CPAN's inability to maintain two running versions in the
same namespace, as mentioned in the
<a href="http://advent.perldancer.org/2014/2">previous article</a>.</p>
<p><a href="https://metacpan.org/module/Dancer2">Dancer2</a> is actually a complete rewrite. It had small portions of the code
moved and some of the documentation was copied over, but mainly it is
completely restructured.</p>
<p>It no longer relies on reinventing the wheel as much. Users simply didn't care
about installing another module or two or three or even more. At the same
time, enough tools we written to still allow you to get away with not being
able to install dependencies, so the entire problem became moot.</p>
<p>For example, Having <a href="https://metacpan.org/module/local::lib">local::lib</a> allows you to install an entire module tree
in a local user's directory (not requiring administrative privileges). Having
<a href="https://metacpan.org/module/fatpacker">fatpacker</a> allows you to fatpack your entire Dancer2 application in a single
file. Having <a href="https://metacpan.org/module/Carton">Carton</a> allows you to package it all nicely. Having <a href="https://metacpan.org/module/Pinto">Pinto</a>
allows you to set up an entire personal CPAN for your company. Things are
much easier.</p>
<p>(Watch for additional articles that cover <a href="https://metacpan.org/module/fatpacker">fatpacker</a> and <a href="https://metacpan.org/module/Carton">Carton</a> in this
advent calendar.)</p>
<p>Additionally, we wanted the ability to make core changes without breaking a lot
of old applications. This doesn't mean a migration is difficult though. Having
two different namespaces allows you to keep your current Dancer 1 applications
running alongside your new Dancer2 applications and make it simple to migrate
when <b>you</b> are ready.</p>
<p>Following are a few tips for migrating your applications to Dancer2, finishing
with one great resource for it at the end.</p>
<h2><a name="it_s_all_about_the_plack"></a>It's all about the Plack</h2>
<p>Dancer originally wasn't built for <a href="https://metacpan.org/module/Plack">Plack</a>. When Plack came out, Dancer has
made the necessary changes to accommodate it. However, it wasn't the leading
spec for Dancer, as it was simply a port of another framework from Ruby.</p>
<p>Dancer2 took a different approach: Plack leads the way. This led to quite a few
changes in removing unnecessary code, producing much more correct behavior,
and providing more deterministic results.</p>
<p>A few examples:</p>
<ul>
<li><a name="item_Each_class_is_an_entire_app"></a><b>Each class is an entire app</b>
<p>A Dancer App is now every class which consumes <a href="https://metacpan.org/module/Dancer2">Dancer2</a>. This means they
can each have their own configuration, allowing different engines:</p>
<pre class="prettyprint">package Admin {
use Dancer2;
...
}
package Public {
use Dancer2;
...
}</pre>
<p>Now <code>Admin</code> and <code>Public</code> are fully independent applications. They
will not share any resources and will be able to have different engines
(template, session, serializer, logger) which will not be shared. No more
worrying about globals.</p>
</li>
<li><a name="item_Removing___script__import_key_for_plackup"></a><b>Removing ':script' import key for plackup</b>
<p>Dancer 1 had the <code>:script</code> import key which would read your command line
arguments to change how the Dancer server would run.</p>
<p>Since <a href="https://metacpan.org/module/Plack">Plack</a> has the <a href="https://metacpan.org/module/plackup">plackup</a> command line tool, it already reads your
command line arguments. Why make a duplicate effort?</p>
</li>
<li><a name="item_Fully_object_oriented"></a><b>Fully object-oriented</b>
<p>Dancer2 has changed its core substantially to be much more object oriented.
Now the core is implemented in objects. The DSL layer simply provides an
interface to those objects.</p>
<p>This makes everything much easier to compose and test.</p>
</li>
<li><a name="item_HTTP__Server__Simple_replaced_with_HTTP__Server__PSGI"></a><b>HTTP::Server::Simple replaced with HTTP::Server::PSGI</b>
<p>Originally Dancer would use <a href="https://metacpan.org/module/HTTP::Server::Simple">HTTP::Server::Simple</a> which supported PSGI, but
it was a pain to use, since it had issues we needed to patch and provided a
dependency we weren't happy about.</p>
<p>As it happens, <a href="https://metacpan.org/module/Plack">Plack</a> comes with a great development server called
<a href="https://metacpan.org/module/HTTP::Server::PSGI">HTTP::Server::PSGI</a>. Since we're building on Plack, we might as well make use
of it. This is why Dancer2 uses it instead.</p>
</li>
</ul>
<h2><a name="migration_in_a_nutshell"></a>Migration in a nutshell</h2>
<p>Okay, but putting all of that aside, how do I migrate?</p>
<p>Well, it really depends on what you do with your application, but here are our
main migration tips:</p>
<ul>
<li><a name="item_Clean_importing"></a><b>Clean importing</b>
<p>All of the importing keywords are unnecessary now, except for <code>appname</code>,
explained below.</p>
</li>
<li><a name="item_Separate_serialized_routes"></a><b>Separate serialized routes</b>
<p>Routes that require serializers should be separated to their own Dancer2 app,
since serializers will try to deserialize all input and serialize all output
in every route in their app scope.</p>
</li>
<li><a name="item_DSL_keyword_changes"></a><b>DSL keyword changes</b>
<p>We tried to change very little of the DSL. <code>load</code> and <code>param_array</code> no
longer exist, and <code>session</code> can also provide the session object, not just
retrieve and set values for keys.</p>
</li>
<li><a name="item_Applications_are_self_dispatching_units"></a><b>Applications are self-dispatching units</b>
<p>As explained above, any module that uses <code>Dancer2</code> becomes a Dancer
Application, which creates a separated dispatcher only for the routes created
under that module namespace.</p>
<p>The application's engines will not be shared with others - an issue that
pained experienced developers of Dancer 1.</p>
<p>If you want to compose multiple Dancer Applications to create a single web
application, you can use <a href="https://metacpan.org/module/Plack::Builder">Plack::Builder</a> and <code>to_app</code>. Stay tuned for
an article explaining this exact situation.</p>
</li>
<li><a name="item_Multiple_packages_for_a_single_app"></a><b>Multiple packages for a single app</b>
<p>Allowing multiple packages to create a single Dancer Application is also
possible using the <code>appname</code> feature. This will also appear in an upcoming
article.</p>
</li>
</ul>
<h2><a name="you_said_something_about_a_great_resource"></a>You said something about a great resource?</h2>
<p>Oh yes!</p>
<p>Writing down all the migration changes between Dancer 1 and Dancer2 would be
too much. Plus, who would check this article after a while again to see if it
was updated? No one, that's who!</p>
<p>Instead, we've compiled a list (with the kind help of Snigdha Dagar) of all
of these changes under <a href="https://metacpan.org/module/Dancer2::Manual::Migration">Dancer2::Manual::Migration</a>.</p>
<p>If you're interested in migrating your applications to Dancer2, or would like
to write a new application and care to know what the differences are, you should
consult it.</p>
<p>Of course we welcome any changes and improvements to this document as it is a
living breathing document (which we hope will not attack us during Halloween),
so feel free to submit pull requests, send comments on the mailing list, or
stop by the IRC channel.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Dancer2 has a few changes that promote much more consistent and deterministic
web application development. It reduces the considerations we have to take
into account while providing much more correct implementations for various
pieces.</p>
<p>Our new Migration Document helps new-comers and seasoned developers keep
up-to-date with the changes we've done and how it might affect their future
code.</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X and Mickey Nasriachi for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Dancer2 - starting anew
http://advent.perldancer.org/2014/2
perlhttp://advent.perldancer.org/2014/2Tue, 2 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="dancer2___starting_anew"></a>Dancer2 - starting anew</h1>
<p>It has a different namespace, a different release manager, and a different
repo - <a href="https://metacpan.org/module/Dancer2">Dancer2</a> sounds like a completely new thing, which it is. But it
also isn't.</p>
<h2><a name="the_portsmith_s_history"></a>The portsmith's history</h2>
<p>Dancer started as a Perl port of Sinatra - a successful light web framework
in Ruby. The author of Dancer, Alexis Sukrieh (AKA, sukria), who is also
a Ruby programmer, had enjoyed it so much, he wanted something similar in
Perl. He then began the task of porting Sinatra to Perl under the name
<b>Dancer</b>.</p>
<p><a href="https://metacpan.org/module/Dancer">Dancer</a> had become very successful. In fact it had been so successful a
wonderful warm community grew around it. Users and developers alike sharing
their use cases, giving talks, trainings, writing articles, and even
making it part of their job.</p>
<p>When Dancer became a production framework in various companies, a major
flaw in the design had creeped into sight: the global state. (Chime in
with horror music.)</p>
<p>Many components in Dancer were globals and this shared state made it
impossible to have multiple applications without side-effects. Sukria had
gone underground and returned with <b>Dancer 2</b>. A completely rewritten
framework, based on the same principle as Dancer, sharing the same DSL
and overall design, but lacking the global state which had crippled
Dancer so.</p>
<p>This version promised to be the noble successor.</p>
<h2><a name="the_version_that_never_was"></a>The version that never was</h2>
<p>Unfortunately the code was still incompatible in some ways. Plugins, mainly,
did not work, since the architecture was vastly different. We wanted to
release both a <i>2.0</i> branch and a <i>1.0</i> branch, but CPAN does not allow
that. We then decided to split the namespace to allow both versions to
exist at the same time while we iron out the missing bits. Considering
<b>Mongrel2</b> and even Perl's <a href="https://metacpan.org/module/Amon2">Amon2</a>,
why not <b>Dancer2</b>?</p>
<p>After a few releases, Sukria had to attend to more pressing issues, and
Dancer2 received little attention. Sawyer, who had become the project
leader for production version of Dancer, took Dancer2, and
Yanick Champoux, the amazing French Canadian, had taken the production
version of Dancer under his wing - one of many wings, in fact.</p>
<h2><a name="the_prodigal_daughter"></a>The prodigal daughter</h2>
<p>Following multiple big releases, Dancer2 had become ready for mass usage.
It has a few rough edges, but in most ways, it's in fact much more reliable.</p>
<p>Dancer2 has the following advantages over Dancer 1, amongst others:</p>
<ul>
<li><a name="item_Composable_Dancer_Applications"></a><b>Composable Dancer Applications</b>
<p>Dancer2 Apps are composable units that take care of their own dispatching.
While we have the original <code>dance</code> behavior to dispatch over all registered
applications, we now have much better mechanisms to handle separate
applications without forcing the user to have all or nothing.</p>
<p>This Advent Calendar will feature an article showcasing this functionality
with plenty of explanations on the matter.</p>
</li>
<li><a name="item_Decoupled_DSL_implementation"></a><b>Decoupled DSL implementation</b>
<p>The DSL implementation in Dancer2 is decoupled in a way that allows us to
improve it without changing it for the users. In fact, Dancer2 shares the
majority of the DSL with Dancer 1 and we can keep that working as expected.</p>
</li>
<li><a name="item_Successful_object_system"></a><b>Successful object system</b>
<p>Instead of rolling our own objects, Dancer2 uses <a href="https://metacpan.org/module/Moo">Moo</a>, which provides the
same behavior as <a href="https://metacpan.org/module/Moose">Moose</a> for all the objects we have. It allows us to have
much smarter objects than we did before with lazy attributes, attribute
builders, role composition, and more.</p>
</li>
<li><a name="item_Better_development_server"></a><b>Better development server</b>
<p>Dancer2 uses the <a href="https://metacpan.org/module/Plack">Plack</a> core development server, <a href="https://metacpan.org/module/HTTP::Server::PSGI">HTTP::Server::PSGI</a>,
which provides a more reliable experience. In the past, for Dancer 1, we
had to work around a lot of problems with the development server.</p>
</li>
<li><a name="item_Less_specialized_code"></a><b>Less specialized code</b>
<p>Dancer 1 contained a lot of unnecessary code which was removed in favor of
a proper implementation around Plack: this includes the command line
parsing when importing the DSL, static file serving, testing code, and more.</p>
</li>
<li><a name="item_Robust_CLI_capabilities"></a><b>Robust CLI capabilities</b>
<p>The command-line interface in Dancer2 is written in <a href="https://metacpan.org/module/App::Cmd">App::Cmd</a>, which
allows us to extend it fully, providing interesting command-line features.</p>
<p>We haven't yet gone nuts with it, but now we'll be able to do so, and we
have a few interesting ideas.</p>
</li>
<li><a name="item_Devoted_set_of_developers"></a><b>Devoted set of developers</b>
<p>While Dancer version 1 has been placed into freeze mode, Dancer2 has a
group of developers devoted to it. More and more developers have joined the
core team as well. This includes the aforementioned Yanick, Russell Jenkins,
Mickey Nasriachi, Stefan Hornburg (Racke), Steven Humphrey, Alberto Simões,
and David Precious. Somewhere in there Sawyer X is probably there, but we
can't attest to that - at least not legally.</p>
</li>
</ul>
<p>At the end of the day, though, there is one major consideration we've yet
to mention.</p>
<h2><a name="the_version_that_is"></a>The version that is</h2>
<p>While many users are still on Dancer 1, Dancer2 is ready and waiting, and
we're pooling all of our efforts to improving it. Dancer 1 is on freeze
mode, meaning no new features.</p>
<p>Dancer2 is <b>NOT</b> a new framework, it is simply the next version. When
asked in the past, we explained that this isn't Perl 5 and Perl 6.</p>
<p>Dancer2 might have a few rough edges, but it's much more reliable,
correct, featureful, and a much safer bet than Dancer 1.</p>
<h2><a name="conclusion"></a>Conclusion</h2>
<p>Please consider writing your new code in <a href="https://metacpan.org/module/Dancer2">Dancer2</a> and also porting any
major applications you want to continue to develop. If you find difficulties
in the process, please let us know, so we could fix them.</p>
<p>Be careful though, that's the first step to becoming a contributor! :)</p>
<h2><a name="author"></a>Author</h2>
<p>This article has been written by Sawyer X for the Perl
Dancer Advent Calendar 2014.</p>
<h2><a name="copyright"></a>Copyright</h2>
<p>No copyright retained. Enjoy.</p>
<p>2014 // Sawyer X <code><xsawyerx@cpan.org></code></p>
</div>Another year of Dancing...
http://advent.perldancer.org/2014/1
perlhttp://advent.perldancer.org/2014/1Mon, 1 Dec 2014 00:00:00 -0000<div class="pod-document"><h1><a name="another_year_of_dancing___"></a>Another year of Dancing...</h1>
<p>Welcome to the Dancer advent calendar!</p>
<p>We skipped last year's advent calendar, but we're hoping the articles we
gathered this year will help you learn more about Dancer and
specifically Dancer2, which is the target version of all new applications.</p>
<p>We will show changes Dancer2 has made, features it recently added, a few
tricks, and even survey the code - as well as mention some of our
numerous community contributors, and take a look at the project as a
whole.</p>
<h2><a name="more_and_more_dancers___"></a>More and more dancers...</h2>
<p>Usage of Dancer continues to grow, with more new users added to the
<a href="http://dancer.pm/dancefloor">dancefloor</a>.</p>
<p>If you're using Dancer in your company and would like to appear on the
dancefloor page, please contact us.</p>
<p>Dancer has been spotted as a required/desired skill in several job adverts,
showing the increased uptake of Dancer in corporate web apps. Try
<a href="http://jobs.perl.org/search?q=dancer">searching for Dancer on jobs.perl.org</a>.</p>
<h2><a name="dancer2___a_reality"></a>Dancer2 - a reality</h2>
<p>Far more progress has been made with <a href="https://metacpan.org/module/Dancer2">Dancer2</a>. It is now a fully usable,
robust replacement for Dancer 1. That said, Dancer 1 will continue to be
supported for some time yet and continues to receive bugfixes, support, and
minor improvements.</p>
<p>This article will focus mainly on Dancer2.</p>
<h2><a name="dancer_at_lpw2013"></a>Dancer at LPW2013</h2>
<p>Andrew Solomon ran a free two-hour Dancer 2 training course at last year's
London Perl Workshop. Andrew's course was a hands-on training session to
develop a website with dynamic content using Dancer, during which the attendees
would:</p>
<ul>
<li><a name="item_Learn_about_Dancer2_as_a_framework_and_as_a_language"></a><b>Learn about Dancer2 as a framework and as a language</b>
</li>
<li><a name="item_Implement_route_handlers_using_sessions_and_hooks"></a><b>Implement route handlers using sessions and hooks</b>
</li>
<li><a name="item_Implement_views__templates__and_layouts_using_Template_Toolkit_and_Bootstrap"></a><b>Implement views, templates, and layouts using Template Toolkit and Bootstrap</b>
</li>
<li><a name="item_Understand_the_concept_of_Model_View_Controller"></a><b>Understand the concept of Model-View-Controller</b>
</li>
<li><a name="item_Experience_structuring_code_for_maintainability"></a><b>Experience structuring code for maintainability</b>
</li>
<li><a name="item_Experience_using_object_oriented_Perl_modules"></a><b>Experience using object oriented Perl modules</b>
</li>
<li><a name="item_Understand_all_the_crazy_jargon_above_"></a><b>Understand all the crazy jargon above!</b>
</li>
</ul>
<p>See also Andrew's <a href="http://geekuni.com/perl-web-d2">Perl Web Development</a> course
on geekuni.com.</p>
<h2><a name="dancerconf"></a>DancerConf</h2>
<p>This year in Hancock, New York, the first Dancer conference was held. It
had trainings on <a href="https://metacpan.org/module/Dancer">Dancer</a> (and <a href="https://metacpan.org/module/Dancer2">Dancer2</a>), <a href="https://metacpan.org/module/DBIx::Class">DBIx::Class</a>, and other
related technologies.</p>
<p>We plan on having another conference in 2015 as well.</p>
<h2><a name="dancer_irc_channel_community_grows"></a>Dancer IRC channel community grows</h2>
<p>The community of helpful users on the Dancer IRC channel continues to grow!
You can find us on <code>irc.perl.org</code> in <code>#dancer</code> or <a href="irc://irc.perl.org/dancer">irc://irc.perl.org/dancer</a>
if your system is configured to support <code>irc://</code> links.</p>
<p>If you do not regularly use IRC but wish to join us, there is also a web IRC
client available at <a href="http://dancer.pm/irc">http://dancer.pm/irc</a> for ease of use.</p>
<h2><a name="authors"></a>AUTHORS</h2>
<p>David Precious (BIGPRESH)</p>
<p>Sawyer X (XSAWYERX)</p>
</div>