Dancer Advent Calendar 2016 http://advent.perldancer.org/ Contributing to Dancer http://advent.perldancer.org/2016/24 perl http://advent.perldancer.org/2016/24 Sat, 24 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="contributing_to_dancer"></a>Contributing to Dancer</h1> <p>The Dancer community is a fun, active, and engaged community, dedicated to the advancement of Dancer and the community as a whole. The core team, in particular, relies on the community for bug reports, feature requests, and other information to find out how Dancer is used, what needs fixing, what needs improving, and how we can make the framework better for you. This guide is intended to show you, at a high level, how to get involved in the community, and things you can do to help further Dancer development and the community.</p> <p>Note: This applies primarily to Dancer2, but works for Dancer1 in some regards. Dancer1 is not open for new feature development, but is actively maintained in a support-only mode; bug fixes and security patches are incorporated in as timely a manner as possible. If you have a feature idea and are using Dancer1, check the docs to see if it has already been implemented, and if not, get hacking on Dancer2!</p> <h2><a name="report_a_bug"></a>Report a Bug</h2> <p>This is perhaps the easiest way to get involved, and one of the most important for the project. If you run into a bug while using Dancer - be it in the core framework, or a plugin - <b>please</b> report it! While you can report it in Dancer's IRC channel, it is not the most reliable reporting method available (that's not to say your report will get ignored there!).</p> <p>Development of Dancer happens on Github. Your best bet for reporting a bug in Dancer is to go to the <a href="https://github.com/PerlDancer/Dancer2/issues">issue tracker on GitHub</a>. Before submitting a new bug, please be courteous and look to see if there is already an open issue for the problem you are observing, and if so, add whatever additional information you have to the existing issue.</p> <p>No matter how well we test Dancer during development, there is no way for us to find all of the potential bugs that may arise. The Core Team and the Dancer community depends on <b>you</b> to report bugs that you find along the way!</p> <h2><a name="irc"></a>IRC</h2> <p>A great way to participate and contribute to the Dancer project is to be active on the IRC channel. The Dancer Core Team strives to maintain a friendly and civil environment on the channel at all times to all users.</p> <p>To get started, all you have to do is point your favorite IRC client to <code>irg.perl.org#dancer</code> and you're off and running. Don't have an IRC client? The <a href="https://chat.mibbit.com/?channel=%23dancer&amp;server=irc.perl.org">web interface</a> is just a click away! Ask a question, answer a question, pitch your plugin idea... there are a number of ways for you to get involved.</p> <p>All users are protected by our <a href="https://metacpan.org/pod/distribution/Dancer2/lib/Dancer2/Policy.pod">community policy and community standards</a> document. The Core Team takes violations of this policy very seriously.</p> <h2><a name="sending_a_documentation_patch"></a>Sending a Documentation Patch</h2> <p>This is one of the easiest ways to get involved, and how yours truly got his start in the Dancer community (so I know for a fact this is an effective way!). We as developers are not always the best at documenting our own work, no matter how hard we try. We are biased, and used to looking at our work in a particular way, and we cannot always explain how something should be used in the best way, or document things in such a way that it answers all the questons a user may have. Dancer2 is no exception.</p> <p>Did you find a particular area of the docs to be hard to understand? Clarify it and send us a pull request on GitHub. Did we forget to document a method or configuration setting? Send us a patch! Dancer's documentation is a living work, and will evolve and improve over time with the help of our community.</p> <p>Another useful addition to the documentation is to add a recipe to the <a href="https://metacpan.org/module/Dancer2::Cookbook">cookbook</a>. It's a great place to show a useful tip that doesn't really fit elsewhere in the documentation.</p> <h2><a name="taking_an_issue_from_the_github_queue"></a>Taking an Issue from the GitHub Queue</h2> <p>At the time of this writing, there are 82 current issues in the GitHub queue, 13 of which are labelled Beginner Suitable. A great way to help out the Dancer Core Team and the community is to pick up one of these issues, hack on it, and send us a pull request. No matter what your level of expertise is, there is something in the issue queue that will be suitable for you.</p> <p>Want to get your pull request looked at even quicker? By making sure your pull request adequetely tests the issue you have tackled, it helps the Core Team fast track your work to the approval stage (because we don't have to write the tests...).</p> <p>We try to evaluate pull requests as quickly as we can. Please don't get discouraged if it takes us a bit. A gentle reminder now and then is even ok, but remember we are all volunteers doing this for our love of Dancer too. :)</p> <p>Are you not that familiar with GitHub? We accept patches in any format you can provider, but we are also happy to help you with your first pull request. If you want a walk through of the process, hit up one of the Core Team members on IRC and we will be happy to help you out.</p> <p><b>Note:</b> To get started hacking, make sure you have <a href="https://metacpan.org/module/Dist::Zilla">Dist::Zilla</a> installed, as well as <a href="https://metacpan.org/module/Dist::Zilla::PluginBundle::Dancer">Dist::Zilla::PluginBundle::Dancer</a>, which has essential plugins we use to build Dancer2.</p> <h2><a name="writing_a_plugin"></a>Writing a Plugin</h2> <p>One of the beauties of Dancer is its extendability, and this extendability is provided through a robust plugin system. While there are many plugins available in the Dancer ecosystem, there is always room for more! Do you have an itch to scratch? Have some code that you use over and over again that you think other members of the community might benefit from? Release that as a plugin, throw it on CPAN, and tell the community about it!</p> <p>Stuck for a plugin idea? Here's a few to get you started:</p> <p>- <a href="https://metacpan.org/module/Text::Handlebars">Text::Handlebars</a> - <a href="https://metacpan.org/module/Log::Log4Perl">Log::Log4Perl</a> - <a href="https://metacpan.org/module/Log::Any">Log::Any</a></p> <h2><a name="wrapping_up"></a>Wrapping Up</h2> <p>We've covered some of the ways that you can get involved in Dancer project. No matter what level of experience you have with Perl or Dancer, everyone has a useful idea or skill they can contribute to the Dancer project and its community. So what are you waiting for? :)</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Jason A. Crome (CromeDome) <code>cromedome@cpan.org</code> for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> </div> How to avoid XSS issues easily http://advent.perldancer.org/2016/23 perl http://advent.perldancer.org/2016/23 Fri, 23 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="how_to_avoid_xss_issues_easily"></a>How to avoid XSS issues easily</h1> <p>XSS (fancy-talk for "Cross Side Scripting") is the security attack of injecting javascript into a page so that some other poor user will accidentally run unintentionally (and often with no knowledge of it either). Pretty cool, huh? Also pretty destructive.</p> <h2><a name="the_trick_about_xss"></a>The trick about XSS</h2> <p>The entire trick about XSS is that is works using a bigger principle of which you must have heard: Code injection!</p> <h2><a name="the_trick_about_code_injections"></a>The trick about code injections</h2> <p>Code injections only work due to one mistake we make. Here is the trick: trust. Trust is the problem. Just trust.</p> <h2><a name="ne_never_"></a>Ne? Never!</h2> <p>Of course we all know not to trust users. So why does this still happen? Because we don't realize where we implicitly trust them. Here's an example: Parameters in templates and queries.</p> <h2><a name="templates"></a>Templates</h2> <p>Probably the most common source of XSS attacks is our templates.</p> <p>When we render a template, we provide a user with something to display, but because it's HTML, we also provide them with something they can <i>run</i>. If the template renders as HTML, the HTML can contain Javascript. It can be at the end, or even embedded.</p> <p><i>Every HTML can contain Javascript</i>.</p> <p>Uh oh. This means that if we create the HTML... we can accidentally create HTML that can contain Javascript. If a user can control how the HTML is created, a user can control <i>what</i> kind of Javascript is created with it, even if it wasn't supposed to contain any code.</p> <p>Let's write a small example in Perl:</p> <pre class="prettyprint">my $name_from_user = prompt('Please enter your name: '); render_template( 'template.tmpl', { 'name' =&gt; $name_from_user' } );</pre> <p>Now let's assume the user gave the following as the name:</p> <pre class="prettyprint">Sawyer&lt;javascript&gt;alert("Hey, what's up?")&lt;/javascript&gt;</pre> <p>This means that if we just use the variable <code>name</code> in the template, we're accidentally adding Javascript code. Thus, XSS is born!</p> <h2><a name="why_is_this_bad"></a>Why is this bad?</h2> <p>Simple!</p> <p>If I registered with that name, and Alice goes to a page that shows all the usernames, then Alice gets HTML that has my code in it. Alice's browser runs the Javascript and now gets a pop-up.</p> <p>Next time instead of a pop-up, I can just have it send the current browser cookies and passwords to some remote server I have.</p> <p>Or maybe I want to force Alice to go to some other website using a Javascript redirect and try to get her to purchase a product on which I get a commission? (I honestly did not just come up with it, I had to resolve such a problem.)</p> <p>Or maybe one of the other options I have when I can just run any Javascript code I want.</p> <h2><a name="queries"></a>Queries</h2> <p>Another such example of trusted parameters is in queries. By using parameters we provided from the user in our queries, we provide inherent trust in their content as legal, correct, valid, and non-destructive SQL. That's often not the case, whether in honest mistake or in malice.</p> <p>If you are using value placeholders in <a href="https://metacpan.org/module/DBI">DBI</a>, you're at least ahead of the curb, making sure it will get quoted correctly, but if you're just creating your own SQL code by using variables in the construction, you're putting yourself and your data at risk.</p> <h2><a name="parameters"></a>Parameters</h2> <p>But now you're thinking, "I know about this. I just escape all my variables". Good job! But what do you do about parameters? Do you validate and escape them before using them? Have you ever used a parameter in your template?</p> <p>Imagine the following code:</p> <pre class="prettyprint">get '/' =&gt; sub { my $name_from_user = query_parameters-&gt;get('name'); # render the "index" template template 'index' =&gt; { 'name' =&gt; $name_from_user, }; };</pre> <p>The above code, the likes of which has been spotted by security, does just that. He takes input from the user and sends it to the template to be used. Injection complete.</p> <pre class="prettyprint">get '/' =&gt; sub { if ( failed_to_do_something ) { redirect '/error?This%20Failed'; } ... };</pre> <p>Now we redirect to a page that uses the parameter to know <i>what</i> the error message is, it's content verbatim. A user that sees it can provide a different error instead and send it to someone else, in which case the error string can be javascript code that steals information. Whoops again!</p> <h2><a name="fixes"></a>Fixes</h2> <p>To fix, we can apply any of the following mechanisms:</p> <ul> <li> <p>Continue to HTML escape <i>every</i> variable used, either in routing code or in the template.</p> </li> <li> <p>Check user input better. If it's not a simple string, it fails. Make sure you allow Unicode character where appropriate!</p> </li> <li> <p>In the example of the error, we could provide a key for a known error (like <code>/error?ErrorID=1</code>) and check that it's only a digit and only display the correlating error messages, which we have full control over.</p> </li> </ul> <p>Escaping in the template is a good practice, since it is the boundary between one system and another. However, the boundary between the user input and your variables exists as well, and defending against it is also important.</p> <h2><a name="conclusion"></a>Conclusion</h2> <p>The conclusion is simple: Parameters are not variables.</p> <p>While many of the template variables were at some point parameters from a user, there is still a fundamental difference between them. This difference (which makes the basis for all of these mistakes) is that parameters and template variables are substantially different things.</p> <p>Parameters come from the user. Template variables come from us. While we can trust ourselves (for the most part), we cannot trust what comes from the user, whether it's maliciously or just an honest mistake.</p> <p>Separating the two protects us from mistakenly using one verbatim for the other, and keeping the security team off our back. :)</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> The new Dancer2 plugin system http://advent.perldancer.org/2016/22 perl http://advent.perldancer.org/2016/22 Thu, 22 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="the_new_dancer2_plugin_system"></a>The new Dancer2 plugin system</h1> <p>The biggest milestone this year in Dancer2 was version 0.200000, which introduced the long-awaited, completely reworked Dancer2 plugin system.</p> <p>The previous plugin system suffered several key issues, all of which are now resolved by this new plugin systems.</p> <p>Plugins are now easy to write and are far more capable than they were before.</p> <h2><a name="your_first_plugin"></a>Your first plugin</h2> <p>When using the new plugin systems, you need only load a single class:</p> <pre class="prettyprint">package Dancer2::Plugin::MyPlugin; use strict; use warnings; use Dancer2::Plugin;</pre> <p>You now have a full object oriented framework, which means you have attributes:</p> <pre class="prettyprint">has 'name' =&gt; ( 'is' =&gt; 'ro', 'default' =&gt; sub {'Sawyer'}, );</pre> <p>If we want to export any keywords, we only need to call the right keyword:</p> <pre class="prettyprint">plugin_keywords('name');</pre> <p>We can also call DSL by using the <code>dsl</code> method. Our object oriented system will run the <code>BUILD</code> method as soon as a new plugin object is loaded:</p> <pre class="prettyprint">sub BUILD { my $self = shift; $self-&gt;dsl-&gt;get( '/', sub { $self-&gt;dsl-&gt;template( 'index', { 'name' =&gt; $self-&gt;name }, ); } ); }</pre> <h2><a name="configuring_your_plugin"></a>Configuring your plugin</h2> <p>Your applications can now use the plugin, and even provide values for them:</p> <pre class="prettyprint"># In your config.yml: plugins: MyPlugin: name: "Yanick"</pre> <p>Then later you can reach them using the <code>config</code> attribute:</p> <pre class="prettyprint">has 'name' =&gt; ( 'is' =&gt; 'ro', 'default' =&gt; sub { return config-&gt;{'name'} || 'Sawyer'; }, );</pre> <p>However, note that configurations will not update the attributes once they are set.</p> <h3><a name="using_other_plugins"></a>Using other plugins</h3> <p>You can use additional plugins within your plugin - a big thorn in the side of plugin developers until this new system.</p> <pre class="prettyprint">package Dancer2::Plugin::Foo; use strict; use warnings; use Dancer2::Plugin; use Dancer2::Plugin::Bar; # You can now use keywords from Dancer2::Plugin::Bar</pre> <h3><a name="hooks"></a>Hooks</h3> <p>You can provide your own hooks using the <code>plugin_hooks</code>. Users can register actions to these hooks and you can then execute these hooks from your application:</p> <pre class="prettyprint">plugin_keywords('my_keyword'); plugin_hooks('my_hook'); sub my_keyword { my $self = shift; $self-&gt;execute_plugin_hook('my_hook'); }</pre> <p>You can also call hooks available in the application:</p> <pre class="prettyprint">$self-&gt;app-&gt;execute_hook('on_route_exception');</pre> <h3><a name="subclassing"></a>Subclassing</h3> <p>You can subclass other plugins:</p> <pre class="prettyprint">package Dancer2::Plugin::Subclass; use strict; use warnings; # Get keywords use Dancer2::Plugin; # Extend extends('Dancer2::Plugin::Parent'); # Export this keyword as well plugin_keywords('keyword_from_parent'); # redefine it sub keyword_from_parent { my ( $self, @args_from_user ) = @_; my @args = @args_from_user; if ( !@args ) { @args = ( 'our', 'default', 'args' ); } # Call the parent keyword $self-&gt;SUPER::keyword_from_parent(@args); } 1;</pre> <h3><a name="utilize_existing_plugins"></a>Utilize existing plugins</h3> <p>From version 0.205000, you can now easily locate additional plugins and use their abilities:</p> <pre class="prettyprint">package Dancer2::Plugin::Special; use strict; use warnings; use Dancer2::Plugin; plugin_keywords('special'); sub special { my $self = shift; my $basic_plugin = $self-&gt;find_plugin('Dancer2::Plugin::Basic') or $self-&gt;dsl-&gt;send_error( 'Please load Dancer2::Plugin::Basic', 500 ); my $basic = $basic_plugin-&gt;normal_keyword; return "Special $basic"; } 1;</pre> <p>Now a user needs to load both plugins, and they will work together.</p> <pre class="prettyprint">package MyApp; use Dancer2; use Dancer2::Plugin::Basic; use Dancer2::Plugin::Special;</pre> <h2><a name="summary"></a>Summary</h2> <p>All the details are available in <a href="https://metacpan.org/module/Dancer2::Plugin">Dancer2::Plugin</a>. There is at least one extra feature I haven't covered, just waiting for you to find it. Here's a clue: Attributes exporting. :)</p> <p>Now with the new plugin system in place, we can not only provide consistent and highly-capable plugins, but introduce new stable features in the future.</p> <p>Keep in touch to see where it leads us!</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Reducing boilerplate and managing exports in Dancer2 http://advent.perldancer.org/2016/21 perl http://advent.perldancer.org/2016/21 Wed, 21 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="reducing_boilerplate_and_managing_exports_in_dancer2"></a>Reducing boilerplate and managing exports in Dancer2</h1> <p>Dancer makes it easy to start small and grow fast. Today we will be looking at a techique to help manage that growth.</p> <p>A typical mature Dancer2 app will span multiple packages and each package will make use of Dancer's plugins and other modules available on CPAN.</p> <pre class="prettyprint">use Scalar::Util qw&lt; blessed &gt;; use List::Util qw&lt; first all none sum &gt;; use Dancer2 appname =&gt; 'MyApp'; use Dancer2::Plugin::DBIC qw&lt; schema resultset &gt;; use Dancer2::Plugin::Redis;</pre> <p>After the first couple of files, the copy-pasting becomes tedious. If you later change your mind about what to include, you leave yourself open to errors when you try to call a function you never imported into the package namespace.</p> <h2><a name="what_dancer2_exports"></a>What Dancer2 exports</h2> <p>As a web framework, Dancer2 provides you with many keywords you can use to write your web code. Usually, this presents no problem, but in some cases Dancer2 might give you a function with the same name as a function in another module you wish to use. For example, Dancer2 provides a function <code>any</code>, so you can write endpoints that work on multiple HTTP verbs, while <a href="https://metacpan.org/module/List::Util">List::Util</a> provides <code>any</code>, a function which returns a true value if at least one item in a list matches a condition.</p> <p>If you want to use <a href="https://metacpan.org/module/List::Util/any">List::Util/any</a> in a package where Dancer2 has been <code>use</code>d, you will find you cannot import both at once. Instead, you can qualify the <code>any</code> from <a href="https://metacpan.org/module/List::Util">List::Util</a>:</p> <pre class="prettyprint">any '/page/:id' =&gt; sub { my $id = param('id'); send_error("Blocked!", 401) if List::Util::any { $_ eq $id } @blocked_resources; template 'page', { id =&gt; $id }; };</pre> <p>If you're using the <code>any</code> from List::Util more frequently than Dancer's <code>any</code>, then you might decide you prefer to qualify the latter and import the former.</p> <p>However, you cannot selectively import functions from Dancer2, and you cannot use the qualified form <code>Dancer2::any</code>, because there isn't actually an <code>any</code> function in the <code>Dancer2</code> package.</p> <p>The reason for this is that Dancer2's <code>import</code> function (which is called when you <code>use</code> it) does something clever, so that you can have multiple separate Dancer2 apps running in the same perl instance.</p> <pre class="prettyprint">use Dancer2 appname =&gt; 'MyApp';</pre> <p>NB: See <a href="http://advent.perldancer.org/2014/10">http://advent.perldancer.org/2014/10</a> for more on <code>appname</code> and running multiple apps.</p> <p>At this point, rather than exporting the function in the usual way, Dancer2 creates a new function in your package namespace, which calls a method of the same name on a <a href="https://metacpan.org/module/Dancer2::Core::App">Dancer2::Core::App</a> object which it has created for you (NB: most of the methods are actually in the <a href="https://metacpan.org/module/Dancer2::Role::DSL">Dancer2::Role::DSL</a> class).</p> <p><b>So is there any way to control which parts of Dancer's DSL to import?</b></p> <p>The answer is yes - but you need to write another package of your own to act as a fa&#xe7;ade.</p> <h2><a name="write_your_own_dsl"></a>Write your own DSL</h2> <p>The solution is to write a package which <code>use</code>s Dancer, and which provides the syntax you want to all your other packages.</p> <p>A simple package would look like:</p> <pre class="prettyprint">package MyApp::DSL; use Dancer2 appname =&gt; MyApp; use Exporter; 1;</pre> <p>(NB: DSL stands for "Domain Specific Language", and in this case is just a small collection of functions. Dancer is a DSL for writing Plack-based web apps).</p> <p>This would provide access to the Dancer DSL as follows:</p> <pre class="prettyprint">use MyApp::DSL; MyApp::DSL::get('/' =&gt; sub { ... });</pre> <p>Having to prefix everything with <code>MyApp::DSL::</code> isn't very nice, though.</p> <p>Modules like <a href="https://metacpan.org/module/Exporter">Exporter</a> provide a way to explicitly request that symbols be exported, for instance:</p> <pre class="prettyprint">package MyApp::DSL; use Dancer2 appname =&gt; 'MyApp'; use Exporter qw&lt; import &gt;; our @EXPORT_OK = qw&lt; get post put any del &gt;; 1;</pre> <p>Now you can write:</p> <pre class="prettyprint">use MyApp::DSL qw&lt; get post put del &gt;; get '/' =&gt; sub { ... };</pre> <p>Or maybe in another route, you just want to retrieve values from your config? That's ok, too:</p> <pre class="prettyprint">use MyApp::DSL qw&lt; config &gt;; my @plugins = keys %{ config('plugins') };</pre> <p>By listing functions in <code>@EXPORT_OK</code>, we have allowed them to be exported when they are specified in the <code>use</code> statement.</p> <p>Note that a limitation of this approach is that you need at least one package per app. If you're only running one app then this won't be an issue.</p> <h2><a name="group_your_exports_with_tags"></a>Group your exports with tags</h2> <p>Chances are you don't want to name each and every function you need in your <code>use</code> statement in every. Luckily, Exporter provides more options, too. Populating <code>@EXPORT</code> will cause those functions to always be exported. You can also use <code>%EXPORT_TAGS</code> to export groups of symbols.</p> <p>Don't forget, it's not just Dancer2's functions that you can put in your DSL package. If you have other functions you use frequently and want to make available across your whole app (such as <a href="https://metacpan.org/module/Scalar::Util/blessed">Scalar::Util/blessed</a>), you can add them too.</p> <p>This also gives you the opportunity to think about separation of concerns: for instance, you may decide that your route handling packages need access to all of Dancer2's functions, whereas the packages which handle your business logic and flow control don't need the route handling functions, while your schema packages have yet another set of functions.</p> <p>One strategy therefore is to create a different tag for each group of concerns, e.g. <code>:controller</code>, <code>:model</code>, <code>:route</code>, etc. Alternatively, the tags could represent where the functions come from, e.g. <code>:util</code>, <code>:config</code>, <code>:storage</code>, <code>:routing</code>, etc.</p> <p>So now you know enough to be able to replace</p> <pre class="prettyprint">use Scalar::Util qw&lt; blessed &gt;; use List::Util qw&lt; first all none sum &gt;; use Dancer2 appname =&gt; 'MyApp'; use Dancer2::Plugin::DBIC qw&lt; schema resultset &gt;; use Dancer2::Plugin::Redis;</pre> <p>with an expression like:</p> <pre class="prettyprint">use MyApp::DSL qw&lt; :util :storage :config &gt;;</pre> <p>or:</p> <pre class="prettyprint">use MyApp::DSL qw&lt; :model &gt;;</pre> <h2><a name="author"></a>Author</h2> <p>This article was written by Daniel Perrett <code>&lt;perrettdl@googlemail.com&gt;</code> for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>&#xa9; 2016 Daniel Perrett; you are free to reuse code without restriction and text under the <a href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike License 4.0</a>.</p> </div> send_as BEER => 'Christmas Cheer' http://advent.perldancer.org/2016/20 perl http://advent.perldancer.org/2016/20 Tue, 20 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="send_as_beer___gt___christmas_cheer_"></a>send_as BEER =&gt; 'Christmas Cheer'</h1> <p>One difference between Dancer and Dancer2 is that serializers are "Always or never". Sawyer X's <a href="http://advent.perldancer.org/2014/11">2014 advent article</a> explains why this change was important.</p> <p>However one question that arose several times during 2015 from keen Dancer2 users was</p> <pre class="prettyprint">"How do you return HTML from a specific route when we have a serialization engine configured?"</pre> <p>Back then, the best advice was to "split" your app into two distinct applications and use <code>Plack::Builder</code> to glue them back together.</p> <pre class="prettyprint"># bin/app.psgi use Plack::Builder; use MyApp; use MyApp::API; builder { mount '/api' =&gt; MyApp::API-&gt;to_app; mount '/' =&gt; MyApp-&gt;to_app; };</pre> <p>However, if you have a small number of routes that required a template engine (or a small number that needed a serialization engine), the effort involved was onerous.</p> <p>Other suboptimal solutions (including the use of eldritch horrors) were proposed in issues on github prior to a suggestion to use a combination of Dancer2's <code>send_file</code> and <code>to_json</code> using an in-memory file handle:</p> <pre class="prettyprint">set serializer =&gt; 'JSON'; set template =&gt; 'template_toolkit'; get '/html/route' =&gt; sub { my $html = encode( 'UTF-8', template('awesome_template') ); content_type =&gt; ''text/html; charset=UTF-8'; send_file \$html; # sends html };</pre> <p>Which just works; but involves excessive boilerplate and one needs to take care with text encodings. That's not the Dancer way!</p> <h2><a name="a_prototype_solution__dancer2__plugin__sendas"></a>A prototype solution: Dancer2::Plugin::SendAs</h2> <p>Conferences have many benefits! There is the awesome talks, the hallway track, the benefits of getting a group together and discussing a problem face-to-face, or just having some time away to think about a particular problem.</p> <p>During some conference related downtime in 2015, <a href="https://metacpan.org/module/Dancer2::Plugin::SendAs">Dancer2::Plugin::SendAs</a> was spec'd and implemented to encapsulate the previous patten into a simple to use c&lt;send_as&gt; keyword:</p> <pre class="prettyprint">use Dancer2::Plugin::SendAs; get '/api/thing' =&gt; sub { send_as JSON =&gt; { thing =&gt; { to =&gt; [ 'return' ] } }; };</pre> <p>Any Dancer2 serializer was supported, as well as HTML output:</p> <pre class="prettyprint">get '/api' =&gt; sub { send_as HTML =&gt; template( 'instructions' ); };</pre> <p>Simple. Easy. Neat. Now that's the Dancer way!</p> <h2><a name="from_plugin_to_core"></a>From Plugin to Core</h2> <p>The <code>SendAs</code> plugin solved a problem many Dancers' encountered. The core team decided to move the plugins' functionality into core in early 2016. (Did you know the <code>to_json</code> and <code>from_json</code> keywords started as a plugin too?)</p> <p>After cleaning up some edge cases and tweaking features, c&lt;send_as&gt; became a core keyword in the c&lt;0.200000&gt; release.</p> <p>The key differences in the core implemantation are</p> <ul> <li><a name="item_Serializers_must_use_the_appropriate_casing_of_their_names__eg___code_JSON__code__or__code_Sereal__code_____code_HTML__code__is_special_cased_for_returning_HTML_content__and_must_be_in_upper_case_"></a><b>Serializers must use the appropriate casing of their names. eg. <code>JSON</code> or <code>Sereal</code>. <code>HTML</code> is special cased for returning HTML content, and must be in upper case.</b> </li> <li><a name="item_Serializers_will_load_settings_from_the_applications_configuration_"></a><b>Serializers will load settings from the applications configuration.</b> </li> </ul> <p>Like <code>send_file</code>, the <code>send_as</code> keyword returns immediately from a route, allowing <code>send_as</code> to short-circuit route logic, even when a serializer is defined:</p> <pre class="prettyprint">set serializer =&gt; 'JSON'; set template =&gt; 'template_toolkit'; post '/api/:id' =&gt; sub { my $id = request-&gt;route_parameter-&gt;get('id'); if ( $id !~ m/^[0-9]+$/ ) { # send HTML error page status 500; send_as HTML =&gt; template('error'); } # Continue with the rest of route logic if id was an integer # Returns JSON content ... };</pre> <p><code>Dancer2::Plugin::SendAs</code> remains on the CPAN (deprecated) for posterity.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Russell (veryrusty) Jenkins for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>2016 // Russell (veryrusty) Jenkins</p> </div> change_session_id http://advent.perldancer.org/2016/19 perl http://advent.perldancer.org/2016/19 Mon, 19 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="change_session_id"></a>change_session_id</h1> <p>It is considered good security practice, and is a requirement of a number of established security standards, to change session ID on any change of privilege level. For starters you should consider doing this on user login, and possibly at any other time a user has some privilege added or removed.</p> <h2><a name="session_destruction"></a>Session destruction</h2> <p>Destroying a session in <a href="https://metacpan.org/module/Dancer2">Dancer2</a> has always been possible using <a href="https://metacpan.org/module/Dancer2::Core::App/destroy_session">Dancer2::Core::App/destroy_session</a> like so:</p> <pre class="prettyprint">app-&gt;destroy_session;</pre> <p>Session destruction by its very nature causes the session ID to change since the server instructs the client to forget the session ID, send it a new session ID and also destroys any session data held on the server. This is considered a "good thing" when a user logs out of an application but it is not very useful when a user logs in and you want to keep existing session data such as cart products.</p> <h2><a name="change_session_id"></a>change_session_id</h2> <p><a href="https://metacpan.org/module/Dancer2::Core::App/change_session_id">Dancer2::Core::App/change_session_id</a> to the rescue!</p> <p>If you are using version 0.610 or later of <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Extensible">Dancer2::Plugin::Auth::Extensible</a> to handle authentication and authorisation then you already have <code>change_session_id</code> called on successful login. If you are using some other solution then you want to do something like this:</p> <pre class="prettyprint">post '/login' =&gt; sub { my $username = body_parameters-&gt;get("username"); my $password = body_parameters-&gt;get("password"); if ( my_authentication_check( $username, $password ) ) { # login successful app-&gt;change_session_id; } };</pre> <p>You might also want to consider calling <code>change_session_id</code> after successful password change.</p> <h2><a name="the_gory_details"></a>The gory details</h2> <p>This part is particularly relevant to implementors of session engines.</p> <h3><a name="native_session_engine_support"></a>Native session engine support</h3> <p>All session engines should implement the private method <code>_change_id</code> which is called like so:</p> <pre class="prettyprint">$session_engine-&gt;_change_id( $old_id, $new_id )</pre> <p>Where <code>$old_id</code> and <code>$new_id</code> are the old and new session IDs respectively.</p> <p>The session engine should do whatever is necessary for the ID change to be successful such as changing the key used in the session storage.</p> <p>All file-based session engines including <a href="https://metacpan.org/module/Dancer2::Session::YAML">Dancer2::Session::YAML</a> and <a href="https://metacpan.org/module/Dancer2::Session::JSON">Dancer2::Session::JSON</a> get native support for <code>change_session_id</code> since they consume the <a href="https://metacpan.org/module/Dancer2::Core::Role::SessionFactory::File">Dancer2::Core::Role::SessionFactory::File</a> which provides <code>_change_id</code>.</p> <h3><a name="non_native_fallback_support"></a>Non-native fallback support</h3> <p>If you have a session engine that doesn't implement <code>_change_id</code> then don't worry: we added a fallback mechanism to <a href="https://metacpan.org/module/Dancer2">Dancer2</a> which does this:</p> <pre class="prettyprint">my $session = $self-&gt;session; # grab data, destroy session and store data again my %data = %{$session-&gt;data}; # destroy existing session $self-&gt;destroy_session; # get new session $session = $self-&gt;session; # write data from old session into new # Some engines add session id to data so skip id. while (my ($key, $value) = each %data ) { $session-&gt;write($key =&gt; $value) unless $key eq 'id'; } # clear out destroyed session - no longer relevant $self-&gt;clear_destroyed_session;</pre> <p>This fallback mechanism will hopefully be removed some time in the future.</p> <h2><a name="further_reading"></a>Further reading</h2> <p><a href="https://www.owasp.org/index.php/Session_Management_Cheat_Sheet">OWASP Session Management Cheat Sheet</a>.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Peter Mottram for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>2016 // Peter Mottram (SysPete) <code>&lt;peter@sysnix.com&gt;</code></p> </div> Asynchronous Dancer2 http://advent.perldancer.org/2016/18 perl http://advent.perldancer.org/2016/18 Sun, 18 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="asynchronous_dancer2"></a>Asynchronous Dancer2</h1> <p>A long awaited feature in Dancer2 is asynchronous (delayed) streaming responses. These are a lot of words, but what they eventually translate to is the ability to respond without blocking additional actions on the same thread. That still doesn't mean much. Let's see if we can clarify that.</p> <h2><a name="blocking_and_non_blocking_outside_web"></a>Blocking and non-blocking outside web</h2> <p>By default, all code in Perl is run synchronously, or in other words, blocking. This means that no single action runs until the previous action ends.</p> <pre class="prettyprint">for ( 1 .. 10 ) { my $result = run_action(); ... }</pre> <p>If we wish to run more than one action at the same time, and assuming they are not dependent on each other, we can use multiple processes:</p> <pre class="prettyprint">for ( 1 .. 10 ) { my $pid = fork(); defined $pid or die "Cannot fork: $!\n"; if ( $pid == 0 ) { my $result = run_action(); ... } else { # this is the parent # which is meaningless here... } }</pre> <p>This will run each of them separately. If we have an event loop, we can schedule these actions using the event loop and provide a callback for handling the results:</p> <pre class="prettyprint">for ( 1 .. 10 ) { # this isn't a real function # it depends on your event loop of choice schedule_action_on_event_loop( sub { my $result = shift; ... } ); }</pre> <h2><a name="within_the_web_environment"></a>Within the web environment</h2> <p>When working on a website, any response which takes a while to complete will hang the entire thread waiting for the action to finish and the user to receive a response. Additionally, any request which requires multiple blocking functions, it will take longer to complete, since we wait for each request.</p> <p>In order to handle this, a common technique is to use asynchronous syntax. Not all event loops support them and many provide their own event loop in order to handle it, forcing you to use their syntax only.</p> <p>Dancer2 recently added asynchronous syntax which is not bound to any existing event loop, making it possible to pick your own.</p> <h2><a name="asynchronous_in_dancer2"></a>Asynchronous in Dancer2</h2> <p>Let's assume we want to run a web server with a single thread that does not fork. We can handle multiple users by responding asynchronously without forcing the next user to wait in line:</p> <pre class="prettyprint">get '/' =&gt; sub { delayed { flush; content template 'index'; done; }; };</pre> <p>This is a simple endpoint that doesn't do anything special, but it allows us to understand the existing syntax before we try something more complicated.</p> <p>The <code>delayed</code> keyword begins an asynchronous response. It registers within your web server (which should be an asynchronous web server, mind you) a response to run asynchronously.</p> <p>The <code>flush</code> keyword sends the headers to the user, allowing you to begin sending content to the user. This is when you begin to stream data.</p> <p>The <code>content</code> keyword sends data to the user. Every time you call <code>content</code>, no matter how many times, you will stream additional data. This data will be sent while being able to handle additional connections and clients within the single process of the web server.</p> <p>The <code>done</code> keyword is simply the way to tell the server to close the connection with the user. You can then continue to run code, but the user will no longer be connected to your web server.</p> <p>So when is this really useful? Let's imagine a situation in which we would like to make several requests to remote servers, and then send the user all of them. We will use <a href="https://metacpan.org/module/AnyEvent">AnyEvent</a> as our event loop of choice (which will run with the <code>Twiggy</code> web server.</p> <pre class="prettyprint">use Dancer2; use AnyEvent; use AnyEvent::HTTP; my @urls = qw&lt;...&gt;; get '/' =&gt; sub { delayed { flush; # keep track of responses with a condvar my $cv = AnyEvent-&gt;condvar; # decide what happens when all responses arrive $cv-&gt;cb( delayed { done; } ); foreach my $url (@urls) { $cv-&gt;begin; http_get $url, delayed { my ( $headers, $body ) = @_; content $body; $cv-&gt;end; }; } }; };</pre> <p>You will notice several new things here.</p> <p>Firstly, we're using a condition variable (<code>condvar</code>), which helps us track all requests. Each time we are about to issue one, we count it using <code>begin</code>. Every time we receive a response, we track it with <code>end</code>.</p> <p>You might also notice we replaced every <code>sub</code> call with <code>delayed</code>. The way <code>delayed</code> works is that it creates an asynchronous <code>sub</code> that has the DSL available. This means that, simply put, every time you wish to have a <code>sub</code> call and use Dancer2 keywords inside it, just replace the word <code>sub</code> with <code>delayed</code>. Everything else is the same.</p> <p>And lastly, we set the <code>done</code> keyword before we run the requests, which doesn't necessarily make much sense, because it happens after. This is how it works with asynchronous programming.</p> <p>Take into account that other event loop might have other syntax, but they should all be similar enough.</p> <h2><a name="future"></a>Future</h2> <p>We have plans on introducing websockets in the future, and they as well, will be asynchronous and streaming.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Configuring Your Dancer Applications http://advent.perldancer.org/2016/17 perl http://advent.perldancer.org/2016/17 Sat, 17 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="configuring_your_dancer_applications"></a>Configuring Your Dancer Applications</h1> <p>It's been a really exciting year for Dancer2 (and an even more exciting two years since the last Advent calendar!), and one of the many things that's been improved is the configuration of Dancer2 applications. While some configuration oddities have been addressed, some additional conveniences have been added as well. Let's get started and explore what's changed!</p> <h2><a name="the_basics"></a>The Basics</h2> <p>Let's assume you are building an application that is contained in a directory named <i> appdir/</i>. The easiest way to configure the application there is with a simple <i> config.yml</i>:</p> <pre class="prettyprint">appname: mytestapp plugins: Debugger: enabled: 1 Auth::Tiny: login_route: '/auth/login'</pre> <p>You are not limited to YAML, however. JSON works just as well:</p> <pre class="prettyprint">{ "appname": "mytestapp", "plugins": { "Debugger": { "enabled": 1 }, "Auth::Tiny": { "login_route": "/auth/login" } } }</pre> <p>In fact, any file format that can be read by <a href="https://metacpan.org/module/Config::Any">Config::Any</a> can be used for your application's config file. TIMTOWTDI!</p> <p><b>Note:</b> The examples that follow assume a YAML file format, but rest assured that these same techniques work with any configuration file format supported by Dancer2.</p> <h2><a name="some_potential_problems"></a>Some Potential Problems</h2> <p>In Dancer1, YAML was the only supported format, and as such, establishing a set order in which configuration files were read was pretty easy: <i>config.yml</i> followed by <i>environments/$environment_name.yml</i>. Since Dancer2 supports multiple file formats, the configuration file loader looks for all files whose name starts with <i>config</i> and merges the results together, and the order in which they are merged is dependent upon the order in which <a href="https://metacpan.org/module/Config::Any">Config::Any</a> tells us what file types it supports. This is not ideal because there is no reliable order in which our configuration files are read - there is no guarantee that <i>config.yml</i> is read before <i>config.json</i>... That's pretty scary in a production environment!</p> <p>To resolve this potential gotcha, set the <code>DANCER_CONFIG_EXT</code> environment variable to the file extension that you wish to use for your configuration files. For example:</p> <pre class="prettyprint">DANCER_CONFIG_EXT=json</pre> <p>If this variable is set, no other type of configuration file will be read, <b>only</b> JSON files. Dancer2 will be nice and let you know if there are other configuration files of other formats present, however.</p> <h2><a name="creating_local_overrides"></a>Creating Local Overrides</h2> <p>Sometimes you will have local overrides for or additions to certain settings found in your <i>config.yml</i> file, such as database settings, that you do not want to commit to your version control system. Thankfully, Dancer2 accounts this by letting you add a file called <i>config_local.yml</i>. Local configuration files are always processed after the files they are named for; that is to say that <i>config.yml</i> is always processed first, followed by <i>config_local.yml</i>.</p> <p>So let's say that your <i>config.yml</i> is the one above, and your <i>config_local.yml</i> contains this:</p> <pre class="prettyprint">DBIC: default: dsn: dbi:Pg:dbname=my_db schema_class: My::Schema user: dbuser password: dbpass options: RaiseError: 1 PrintError: 1</pre> <p>Effectively, your running configuration would be this:</p> <pre class="prettyprint">appname: mytestapp plugins: Debugger: enabled: 1 Auth::Tiny: login_route: '/auth/login' DBIC: default: dsn: dbi:Pg:dbname=my_db schema_class: My::Schema user: dbuser password: dbpass options: RaiseError: 1 PrintError: 1</pre> <p>If you've converted to Dancer2 from Catalyst, this configuration technique should be familiar to you.</p> <h2><a name="configuring_for_multiple_deployment_environments"></a>Configuring for Multiple Deployment Environments</h2> <p>In reality, your local development settings will likely differ from shared development server settings, which will likely be different than staging or production environment settings. To help you with this, Dancer2 lets you specify your runtime environment when running your application:</p> <pre class="prettyprint">DANCER_ENVIRONMENT=staging plackup bin/mytestapp.psgi</pre> <p>This tells Dancer2 to load <i>environments/staging.yml</i> after <i>config.yml</i> and, if it exists, <i>config_local.yml</i>.</p> <p>As with the previous example, the configuration files are merged in order, with settings in <i>environments/staging.yml</i> taking precedence over all others. If you had a <i>environments/staging_local.yml</i> file, it would get read and merged after all other files.</p> <h2><a name="one_final_example__read_all_the_files_"></a>One Final Example: Read All the Files!</h2> <p>If you are using YAML-based configuration files only, and are launching an application in a production environment, these settings:</p> <pre class="prettyprint">DANCER_CONFIG_EXT=yml DANCER_ENVIRONMENT=production</pre> <p>will read the following files (for sake of illustration, let's assume you use every one of these files):</p> <pre class="prettyprint">appdir/config.yml appdir/config_local.yml appdir/environments/production.yml appdir/environments/production_local.yml</pre> <p>Settings found in the last file merged <b>always</b> takes precedence, followed by settings found in the next most recently read file, and so on.</p> <h2><a name="debugging_configuration_issues"></a>Debugging Configuration Issues</h2> <p>If you are ever unsure what order configuration files are being processed in, setting the environment variable <code>DANCER_CONFIG_VERBOSE=1</code> prior to launching your application will show you the order in which files have been loaded.</p> <h2><a name="wrapping_up"></a>Wrapping Up</h2> <p>Dancer2 developers gained a lot of flexibility in how to to configure their applications in 2016. The core team would like to give a shout-out to Jonathan Scott Duff (aka perlpilot) for his work in making this possible.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Jason A. Crome (CromeDome) <code>cromedome@cpan.org</code> for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> </div> Optimizing Dancer2 PT. 5 http://advent.perldancer.org/2016/16 perl http://advent.perldancer.org/2016/16 Fri, 16 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="optimizing_dancer2_pt__5"></a>Optimizing Dancer2 PT. 5</h1> <p>So what do we have planned out for the future? We intend to introduce faster code for us, and more options for you to control the optimizations.</p> <h2><a name="introduce_more_immutability"></a>Introduce more immutability</h2> <p>An important rule in programming is "mutability is from the devil". At least it's what we say. The reason is that mutability (or "state") means constantly (or consistently) checking whether a value has changed, because, well, it can change.</p> <p>Immutability (values that cannot change) do not require checking. They are, by definition, consistent. However, we do pay for recreating values and reinstating immutable values, so sometimes it's worth it to just check instead of recreate.</p> <p>We intend to work harder on introducing more immutability where it affects our speed.</p> <h2><a name="built_in_xs"></a>Built-in XS</h2> <p>We initiated several XS modules for Dancer2 to make use of, such as <a href="https://metacpan.org/module/HTTP::XSHeaders">HTTP::XSHeaders</a> and <a href="https://metacpan.org/module/HTTP::XSCookies">HTTP::XSCookies</a>.</p> <p>We wish to add more optional usage of such fast XS-powered modules, such as <a href="https://metacpan.org/module/Ref::Util">Ref::Util</a>.</p> <p>These will allow you to make things run faster by simply loading these modules.</p> <h2><a name="internal_cleanups"></a>Internal cleanups</h2> <p>There are several slower parts in Dancer2, such as the path resolutions, decoding of input, type constraint checks, and the dispatcher. These are all be improved and we will work on improving them.</p> <h2><a name="faster_catch_most_module"></a>Faster catch-most module</h2> <p>We also intend to introduce a new module to try and both load as many useful plugins and trigger as many improved settings to speed up as much as possible at once.</p> <h2><a name="in_conclusion"></a>In conclusion</h2> <p>It is not hard to optimize and in many cases it is not worth it. However, using the correct modules, middlewares, stack, and code, we can create both faster and - often times - simpler applications.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Optimizing Dancer2 PT. 4 http://advent.perldancer.org/2016/15 perl http://advent.perldancer.org/2016/15 Thu, 15 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="optimizing_dancer2_pt__4"></a>Optimizing Dancer2 PT. 4</h1> <p>After inspecting our stack and infrastructure, it is time to look into our code, inspecting patterns that can be improved in our attempt to speed up our applications.</p> <h2><a name="prevent_unnecessary_actions_with_constants"></a>Prevent unnecessary actions with constants</h2> <p>Many of us don't know that Perl supports constant folding, allowing it to reduce and completely eliminate the running of unnecessary code paths if you give it enough information.</p> <p>An example is the following code:</p> <pre class="prettyprint">use constant { 'DEBUG' =&gt; 0, }; if ( DEBUG()) { debug('This is a debug statement'); }</pre> <p>Perl would know at this case to not even include the <code>debug</code> line, since it will certainly not be reached. You can also control that using an environment variable, to make this more useful:</p> <pre class="prettyprint">use constant { 'DEBUG' =&gt; $ENV{'MYAPP_DEBUG'}, }; if ( DEBUG() ) { debug('This is a debug statement'); }</pre> <p>This allows you to remove unnecessary lines, such as log statements that require debugging or a certain level or logging.</p> <h2><a name="proper_parameters_access"></a>Proper parameters access</h2> <p>Dancer2 introduced new parameter keywords: <code>route_parameters</code>, <code>query_parameters</code>, and <code>body_parameters</code>.</p> <p>Other than the problems when using <code>param</code> or <code>params</code> (review advent article about it), an additional small problem is that it will only return results after parsing all possible parameters. If you have a <b>GET</b> request but someone included body parameters (whether by accident or maliciously), they will be parsed when accessing <code>param</code> or <code>params</code>.</p> <p>However, by using the appropriate parameters keyword, Dancer2 will only parse the correct input.</p> <h2><a name="faster_parameters_access"></a>Faster parameters access</h2> <p>More importantly, all the new keyword represent the parameters using <a href="https://metacpan.org/module/Hash::MultiValue">Hash::MultiValue</a>. This means that you can access them in two ways:</p> <pre class="prettyprint"># no matter how many "name" was provided, you get a single one my $name = query_parameters-&gt;get('name'); # no matter how many "name" was provided, you get an array my @all_names = query_parameters-&gt;get_all('name');</pre> <p>Usually we use only one value, no matter how many were provided. In such case, we can also use the parameters as a hash reference:</p> <pre class="prettyprint">my $name = query_parameters-&gt;get('name'); # faster my $name = query_parameters-&gt;{'name'};</pre> <p>This will only work when we only wish to retrieve one value. It will not work when given multiple values. We will need to use <code>get_all</code> as shown before.</p> <h2><a name="avoid_slow_routing_syntax_"></a>Avoid slow routing syntax:</h2> <p>Dancer2 allows you to control how the flow of the program using various keywords, but the following two are far slower than how you would normally do it.</p> <p>It might be fun to use them, but it's definitely slower.</p> <ul> <li><a name="item__code_pass__code_"></a><b><code>pass</code></b> <p>We suggest avoiding the <code>pass</code> keyword. First, let us explain what it does.</p> <p>Let's assume we have two routes that will match two endpoints:</p> <pre class="prettyprint">get '/:action' =&gt; sub {...}; get '/fail' =&gt; sub {...};</pre> <p>A request to <i>/fail</i> can be handled by both of these routes. While in Dancer2 it works by first-come first-serve, meaning the first route that matches will be the first served, you can still control this, if you wish.</p> <p>The <code>pass</code> keyword will allow you to pass the request to the next one in line. If a request does not <code>pass</code>, it will not reach the next one, and if there is no next request, the application will return a 404.</p> <pre class="prettyprint">get '/:action' =&gt; sub { my $action = route_parameters-&gt;{'action'}; if ( $action eq 'fail' ) { # this will return from the route for you pass; } # every action except 'fail' ... }; get '/fail' =&gt; sub { # handle action 'fail' ... };</pre> <p>However, while this seems pretty enough, it forces the request to go through the matching mechanism again, which can be completely avoided by having direct access using different mechanisms:</p> <ul> <li><a name="item_Reverse_the_routes"></a><b>Reverse the routes</b> <p>If we reverse the routing by having the more exact routes at the top, we will not need to match because they will no longer cause multiple matches:</p> <pre class="prettyprint">get '/fail' =&gt; sub { # handle 'fail' ... }; get '/:action' =&gt; sub { # anything other than 'fail' because it was already served # no need for 'pass' ... };</pre> </li> <li><a name="item_Merge_the_routes"></a><b>Merge the routes</b> <p>At the end of the day what we have is an <code>if</code> condition, and we could simply put that <code>if</code> as part of a single route:</p> <pre class="prettyprint">get '/:action' =&gt; sub { my $action = route_parameters-&gt;{'action'}; if ( $action eq 'fail' ) { # do the work... ... # or move it to a sub and call it: return handle_fail_action(...); } ... };</pre> </li> </ul> </li> <li><a name="item__code_forward__code_"></a><b><code>forward</code></b> <p>The <code>forward</code> keyword is far stronger than <code>pass</code>. While <code>pass</code> simply says "Not it!" with the current request, <code>forward</code> creates a new request and passes it to the Dancer dispatcher to attempt to match it and serve it instead. Simply put, it provides an internal redirect.</p> <pre class="prettyprint">get '/fail/:user' =&gt; sub {...}; get '/:action' =&gt; sub { my $user = query_parameters-&gt;{'user'}; my $action = route_parameters-&gt;{'action'}; if ( $action eq 'fail' ) { forward "/fail/$user"; } };</pre> <p>Notice we receive a parameter from the query and send it then to another route that include two parts. It effectively created a new request and starts from the top. That is also why it is slow.</p> <p>It is better to handle this by either redirecting to the user or passing it to a subroutine that could be shared by both:</p> <pre class="prettyprint">use URI::Escape; sub _handle_fail { my $user = shift; # remember to avoid XSS! my $safe_username = uri_escape($user); ... } get '/fail/:user' =&gt; sub { _handle_fail( query_parameters-&gt;{'user'} ); }; get '/:action' =&gt; sub { my $action = route_parameters-&gt;{'action'}; if ( $action eq 'fail' ) { return _handle_fail( query_parameters-&gt;{'user'} ); } };</pre> <p>Now there is no duplication of code and we only use one subroutine call instead of the entire dispatching engine.</p> </li> </ul> <h2><a name="unnecessary__code_before__code__hook"></a>Unnecessary <code>before</code> hook</h2> <p>There is a common observed pattern of utilizing the <code>before</code> hook when only some routes are required.</p> <p>An example of it is making sure we only serve a specific route securely. (If this seems contrived, it is taken from company code that was shared.)</p> <pre class="prettyprint">hook 'before' =&gt; sub { # check the address of the request if ( request-&gt;address ne '127.0.0.1' ) { # provide a 404 when the user is not local status 404; halt(1); } }; get '/private' =&gt; sub {...};</pre> <p>We then realize that we accidentally blocked everything, so we add the specific route as another test.</p> <pre class="prettyprint">hook 'before' =&gt; sub { if ( request-&gt;path eq '/private' &amp;&amp; request-&gt;address ne '127.0.0.1' ) { status 404; halt(1); } }; get '/private' =&gt; sub {...};</pre> <p>There we go. However, the <code>before</code> route is called on <i>every</i> request and is thus expensive for no reason.</p> <p>We can handle this in several other, better ways:</p> <ul> <li><a name="item_Add_the_code_to_the_code_itself"></a><b>Add the code to the code itself</b> <pre class="prettyprint">get '/private' =&gt; sub { request-&gt;address eq '127.0.0.1' or send_error 404; ... };</pre> <p>This is much more direct, but this might be a longer piece of code and also tedious to add to every route. Instead, we can write code that creates code.</p> </li> <li><a name="item_Decorate_each_route"></a><b>Decorate each route</b> <pre class="prettyprint">sub only_local { my $cb = shift; return sub { request-&gt;address eq '127.0.0.1' or send_error 'File not found', 404; goto &amp;$cb; }; } get '/private' =&gt; only_local sub { ... };</pre> <p>Here we only need to add <code>only_local</code> to every subroutine call, avoiding duplication and making clearer code that performs better.</p> <p>In fact, it is this technology that <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Tiny">Dancer2::Plugin::Auth::Tiny</a> uses for its syntax. It is fairly easy to create a plugin with it.</p> </li> </ul> <h2><a name="render_on_backend_without_layout"></a>Render on backend without layout</h2> <p>Originally, before AJAX, we rendered entire pages on every request. Then with AJAX, we only rendered parts of it and sent over structures to allow rendering it on the client side later on.</p> <p>However, in many cases it is still more affordable from a performance stand-point to render it in the backend.</p> <p>If the data is bigger than the rendering of it (containing information that is used in condition statements, in order to determine what to render) or if the rendering is heavy, it is far better to still render it on the server side. You can set the layout to make sure a template is rendered without a layout.</p> <pre class="prettyprint">get '/data/:user' =&gt; sub { my $data = retrieve_data( route_parameters-&gt;{'user'} ); template 'data' =&gt; { 'user_data' =&gt; $data }; }; get '/' =&gt; sub { my $user = session-&gt;{'id'}; my $data = retrieve_data($user); template 'data' =&gt; { 'user_data' =&gt; $data }; };</pre> <p>And you can, of course, split this further:</p> <pre class="prettyprint">sub _render_data { my $user = shift; my $data = retrieve_data($user); template 'data' =&gt; { 'user_data' =&gt; $data }; }; get '/data/:user' =&gt; sub { return _render_data( route_parameters-&gt;{'user'} ); }; get '/' =&gt; sub { my $data = retrieve_data( session-&gt;{'id'} ); return _render_data($user); };</pre> <h2><a name="asynchronous_cleanups__where_possible_"></a>Asynchronous cleanups (where possible)</h2> <p>Often times we write code that generates data we need to clear and clean up. These cleanups take precious time in which the user is just waiting.</p> <p>There are some servers that support cleaning up stuff asynchronously, which means the user is done with the website, moved on, and the server will work in the background to clean up what we wanted. uWSGI is one web server that has supports for this ability.</p> <h2><a name="less_sugar"></a>Less sugar</h2> <p><a href="https://metacpan.org/module/Try::Tiny">Try::Tiny</a> is an often-used accurate, simple, clean, and recommended module to use when needing a `try`/`catch` pattern. As with many other sugar syntax modules, it is far less performant, and while being a good practice for most cases, when in need for speed, you might to avoid a some of these modules.</p> <p>Since this is probably one of the bigger costs, here's how you can perform a safe and accurate `try`/`catch` without <a href="https://metacpan.org/module/Try::Tiny">Try::Tiny</a>:</p> <pre class="prettyprint">eval { run_action(); # this might die 1; # make sure to result in true } or do { # did it not reach the "1" above? my $error = $@; handle_error($error); };</pre> <h2><a name="coming_next"></a>Coming next</h2> <p>Up until now we covered what you can do to optimize things, but we would also like to share the future plans we have for increasing our optimizations and improving the speed.</p> <p>Our last and final article in this series will focus on that.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Optimizing Dancer2 PT. 3 http://advent.perldancer.org/2016/14 perl http://advent.perldancer.org/2016/14 Wed, 14 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="optimizing_dancer2_pt__3"></a>Optimizing Dancer2 PT. 3</h1> <p>After improving our web server and web server configurations in our previous article, we can now dive deeper into our stack. There is much to gain by deciding how we configure our stack, what technologies we use, and how we architect our platform.</p> <h2><a name="offloading_tasks"></a>Offloading tasks</h2> <p>Have you ever implemented a queue system in a web application? Of course you have! We all have! However, this proves to be a common mistake that must be rectified if we seek to have a fast web application.</p> <p>Queues are not the only example of trying to accomplish as much as possible within the web application instead of offloading it to other components which are more suitable at their given task.</p> <ul> <li><a name="item_Queues"></a><b>Queues</b> <p>Queues are enticing to write since they seem simple at first. We <code>push</code> to an array, <code>pop</code> on the other side, and run. Unfortunately, a proper queue system needs to take into account working across data centers, journaling and crash recovery, and even multiple processes for work.</p> <p>We recommend using a proper queue or proper DB meant for storing and dealing with queues. You can use RabbitMQ for queuing or if you want to use a worker system, you can store your work in Redis.</p> <p>Either way, you shouldn't implement such a grant task yourself inside your web application. It just won't cut it.</p> </li> <li><a name="item_Scheduled_tasks__cron_jobs_"></a><b>Scheduled tasks (cron jobs)</b> <p>Many tasks are performed asynchronously in the web server since they take a long time to run. However, it makes them more fragile, error-prone, and opaque, making it hard to trace and debug.</p> <p>Instead, scheduled task runners are available on common operating systems.</p> </li> <li><a name="item_Caching"></a><b>Caching</b> <p>There is <a href="https://metacpan.org/module/Plack::Middleware::Cache">Plack::Middleware::Cache</a> available, but at the end of the day, caching can definitely be done better by any proper caching server.</p> <p>We recommend Varnish.</p> </li> </ul> <h2><a name="preloading_modules"></a>Preloading modules</h2> <p>Our web applications tend to use many modules, some of which quite heavy. Most web servers fork in order to handle multiple workers. But why waste the start-up time of heavy modules on each fork of the web server? This is what preloading is for.</p> <p>If you load modules before you start your web server, you can allow the web server to fork with the modules already loaded in memory, and to share that memory.</p> <p>While this saves a lot of memory, it also saves the CPU required on every fork generator in order to load the modules.</p> <pre class="prettyprint"># app.psgi use MyApp; # preloading use Moose (); use DBIx::Class (); use AnotherBigModule (); MyApp-&gt;to_app;</pre> <h2><a name="faster_headers_everywhere"></a>Faster headers everywhere</h2> <p>Handling headers is one of the most common tasks performed in a web request. It is done by the caching layer, the reverse proxy, the web server, and your application.</p> <p>The most common module in Perl to handle headers is the old <a href="https://metacpan.org/module/HTTP::Headers">HTTP::Headers</a>, and <i>old</i> is right. <a href="https://metacpan.org/module/Plack">Plack</a> moved to a faster version, aptly named <a href="https://metacpan.org/module/HTTP::Headers::Fast">HTTP::Headers::Fast</a>, which tries to maintain compatibility but improve the speed. It is about 20% faster, which is already a major benefit, since <a href="https://metacpan.org/module/Plack">Plack</a> an make many uses of headers.</p> <p>Dancer2 internally uses <a href="https://metacpan.org/module/HTTP::Headers::Fast">HTTP::Headers::Fast</a> in order to assure faster results, but you can take this one step further by changing what Dancer2 (and Plack) will use, along with any other component in your web application.</p> <p>If you load <a href="https://metacpan.org/module/HTTP::XSHeaders">HTTP::XSHeaders</a> early in your application, it will override the other HTTP libraries (namely <a href="https://metacpan.org/module/HTTP::Headers">HTTP::Headers</a> and <a href="https://metacpan.org/module/HTTP::Headers::Fast">HTTP::Headers::Fast</a>) and changes their code (and subsequently) any code that calls it) to a much higher performant C-based implementation of headers.</p> <pre class="prettyprint"># app.psgi use HTTP::XSHeaders; use MyApp; ...</pre> <h2><a name="reduce_i_o_with_loggers_and_sessions"></a>Reduce I/O with loggers and sessions</h2> <p>Logging and session reading and writing are also frequently performed actions. It also involves I/O, writing to disk, or involve a network operation. Those can be slow.</p> <p>Make sure to maintain a useful logging level in your application, not writing at all levels, to prevent excessive writing to disk or network, and use a fast logger engine.</p> <p>Additionally, usse a memory-based session storage, not the <a href="https://metacpan.org/module/YAML">YAML</a> or <a href="https://metacpan.org/module/JSON">JSON</a> ones, since they both write to disk and serialize - two unnecessary expensive actions.</p> <h2><a name="faster_templating"></a>Faster templating</h2> <p>If you're not writing a web service, you are likely to be using templates. Rendering a template is a simple task, but when using templating frequently, it starts to take more time.</p> <p>If speed is crucial, it is a key point to improve. We recommend using <a href="https://metacpan.org/module/Text::XSlate">Text::XSlate</a> for a blazing fast templating system.</p> <h2><a name="middlewares_aren_t_everything"></a>Middlewares aren't everything</h2> <p>Middlewares are quite beneficial. They allow use to split the work between layers and keep layers simple and thin. However, they are much more expensive than we realize.</p> <p>Each middleware call requires two additional subroutine calls on every request. While calling subroutines in perl 5.24 has been considerably improved in speed (30% faster!), it is still a cost worth realizing and possibly amending.</p> <p>In many cases middlewares need access to information you already have in your application. Benchmark before you either decide to move to middleware, or when contemplating removing them.</p> <h2><a name="reduce_assets_cost"></a>Reduce assets cost</h2> <p>Serving our assets through a CDN or other caching server, or even through our reverse proxy is faster, but we take this one step further by improving the asset files themselves.</p> <p>For images, you can reduce the size and amount of required file transfers by using sprites.</p> <p>For Javascript files, you can both concatenate the files together and reduce their size by minifying them.</p> <h2><a name="coming_next"></a>Coming next</h2> <p>Our next article in this series will deal directly with our application code. How can we write faster code in order to speed up our application?</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Optimizing Dancer2 PT. 2 http://advent.perldancer.org/2016/13 perl http://advent.perldancer.org/2016/13 Tue, 13 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="optimizing_dancer2_pt__2"></a>Optimizing Dancer2 PT. 2</h1> <p>In the previous article we explored the optional modules we can install in order to make things run faster. Other than having them installed, no special changes we required.</p> <p>However, there are much greater changes we can make with greater value. In this article we will discuss changes in our server configuration.</p> <h2><a name="picking_your_server"></a>Picking your server</h2> <p>While <a href="https://metacpan.org/module/Plack">Plack</a> has a built-in server, you wouldn't want to use this. For many the go-to server is Apache, due to its stability and feature abundance. However, its performance is sub-optimal at times.</p> <p>If you're already running a Perl application, you can opt for a Perl-based web server. They perform exceedingly well. Servers like <a href="https://metacpan.org/module/Starman">Starman</a> or <a href="https://metacpan.org/module/Gazelle">Gazelle</a> can provide high-performance.</p> <p>If you're interested in seeking alternatives, <a href="https://metacpan.org/module/uWSGI">...</a> provides a fast web server with support for PSGI protocol. It also one additional special feature: Asynchronous cleanup handlers, which allow you to asynchronously handle cleanup tasks such as clearing intermediate objects, write to disk, log, etc.</p> <h2><a name="faster_sessions"></a>Faster sessions</h2> <p>Applications tend to use sessions.</p> <p>Picking the right session storage is a matter of balance, as with many things. If you are looking for speed, forget about the file-based session storage like JSON or YAML or Sereal. Instead, use Redis or Memcached.</p> <h2><a name="static_file_serving"></a>Static file serving</h2> <p>All your static files are normally served by Dancer2 using a static middleware. It works, but it's far from the fastest solution.</p> <p>Many web servers support serving static files for you, especially if they are also a reverse proxy. NGINX is a fast web server and reverse proxy that can serve the static files for you, with much greater speed, and then run your web application for everything else.</p> <p>If you serve the static files through a different mechanism, you can disable the middleware in Dancer2 that handles it:</p> <pre class="prettyprint"># in your config.yml: static_handler: 0 # or in your MyApp.pm set 'static_handler' =&gt; 0;</pre> <p>Dancer2 will then generate a faster web application by not even checking for static files at all.</p> <p>(This is touching your stack structure, which we will delve into further in the next blog post in this series.)</p> <h2><a name="https___where_appropriate"></a>HTTPS - where appropriate</h2> <p>Security is important but it's not without cost.</p> <p>HTTPS adds additional processing and network time. You might want to reduce some of it for critical parts of the website that do not require security. This is usually a meager amount, but it's worth noting.</p> <p>Take into account, though, that you could lose much more if you make a mistake and do not enable HTTPS where it is needed. In many cases it's preferable to just keep it rather than be in doubt.</p> <h2><a name="coming_next"></a>Coming next</h2> <p>In the next article, we will focus on our stack and explore the architectural changes we can make in order to speed up our web applications.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Optimizing Dancer2 PT. 1 http://advent.perldancer.org/2016/12 perl http://advent.perldancer.org/2016/12 Mon, 12 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="optimizing_dancer2_pt__1"></a>Optimizing Dancer2 PT. 1</h1> <p>One goal we have is making Dancer2 a fast web framework. While we continue to optimize our code, some changes are not possible due to obligations we have to users. However, there are many actions you can take to optimize your Dancer2 web applications.</p> <p>In this series of articles we will explore these actions, in order of the involvement required from you, starting from installing modules to configuring your server, to changing your architecture and code.</p> <p>While some of these suggestions apply to Dancer2, others apply to other frameworks, and even other languages.</p> <h2><a name="built_in_optimizations"></a>Built-in optimizations</h2> <p>In this article we focus on optimizations that are built into Dancer2, but require your involvement. Specifically, this relates to various modules that, if you install them, things will simply run much faster.</p> <h2><a name="why_can_t_it_just_happen_automatically"></a>Why can't it just happen automatically?</h2> <p>The first question, before explaining what you can install, is <i>why</i>. Why can't all of these modules simply be part of Dancer2? In short, users.</p> <p>Dancer2 is used by many users, in various environments, all with different considerations. Some users install it on their machine, while others might use a hosting company.</p> <p>Dancer2 provides a promise to always use Pure-Perl code. This means that we will not, by default, use modules that require a C (or C++) compiler in order to install. This means you can always <a href="https://metacpan.org/module/FatPack">advent-calendar-on-fatpack</a> your application with <a href="https://metacpan.org/module/App::FatPacker">App::FatPacker</a>.</p> <p>Dancer2 will then check whether certain modules are available, and if so, will use those modules instead of the Pure-Perl default implementation. There are various other modules which take the same approach, meaning they in turn will also run faster having certain modules available.</p> <p>We try to list as many as possible of these modules in the documentation and in the metadata for installers, so some might be installed when you install Dancer2. Still, you might want to double check you have them installed.</p> <h2><a name="what_should_i_install"></a>What should I install?</h2> <ul> <li><a name="item__a_href__https___metacpan_org_module_Class__XSAccessor__Class__XSAccessor__a_"></a><b><a href="https://metacpan.org/module/Class::XSAccessor">Class::XSAccessor</a></b> <p>Dancer2 uses <a href="https://metacpan.org/module/Moo">Moo</a> as the object system internally. <a href="https://metacpan.org/module/Moo">Moo</a> itself can be sped up considerably by having this module installed.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_URL__Encode__XS__URL__Encode__XS__a_"></a><b><a href="https://metacpan.org/module/URL::Encode::XS">URL::Encode::XS</a></b> <p>Currently Dancer2 uses <a href="https://metacpan.org/module/URL::Encode">URL::Encode</a> to handle the URL encoding. While we intend to move this coming year to <a href="https://metacpan.org/module/URL::XSEncode">URL::XSEncode</a>, we haven't done so yet. Until we do, we will check whether you have the XS version installed, and if so, we will use that.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_CGI__Deurl__XS__CGI__Deurl__XS__a_"></a><b><a href="https://metacpan.org/module/CGI::Deurl::XS">CGI::Deurl::XS</a></b> <p>No, we don't use <a href="https://metacpan.org/module/CGI">CGI</a>, don't you worry. However, we do parse the query string with this fast module.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_HTTP__Parser__XS__HTTP__Parser__XS__a_"></a><b><a href="https://metacpan.org/module/HTTP::Parser::XS">HTTP::Parser::XS</a></b> <p>Dancer2 uses several components of the <a href="https://metacpan.org/module/Plack">Plack</a> set of utilities. It itself uses this module if it is available, so we recommend installing it.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_YAML__XS__YAML__XS__a_"></a><b><a href="https://metacpan.org/module/YAML::XS">YAML::XS</a></b> <p>The Dancer2 configuration is read by <a href="https://metacpan.org/module/Config::Any">Config::Any</a>, in order to allow you to use any format you prefer. <a href="https://metacpan.org/module/Config::Any">Config::Any</a> will prefer <a href="https://metacpan.org/module/YAML::XS">YAML::XS</a>, if it's available.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_Cpanel__JSON__XS__Cpanel__JSON__XS__a_"></a><b><a href="https://metacpan.org/module/Cpanel::JSON::XS">Cpanel::JSON::XS</a></b> <p>We have moved our code from <a href="https://metacpan.org/module/JSON">JSON</a> to <a href="https://metacpan.org/module/JSON::MaybeXS">JSON::MaybeXS</a>. This makes the Dancer2 automatically try and use an XS JSON parser (preferably <a href="https://metacpan.org/module/Cpanel::JSON::XS">Cpanel::JSON::XS</a>). While it might load <a href="https://metacpan.org/module/JSON::XS">JSON::XS</a>, we recommend <a href="https://metacpan.org/module/Cpanel::JSON::XS">Cpanel::JSON::XS</a> instead.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_HTTP__XSCookies__HTTP__XSCookies__a_"></a><b><a href="https://metacpan.org/module/HTTP::XSCookies">HTTP::XSCookies</a></b> <p>There are several cookie parsing modules on CPAN. There is an XS version, but it doesn't handle everything. Instead, and because of Dancer2, <a href="https://metacpan.org/module/HTTP::XSCookies">HTTP::XSCookies</a> was written. Dancer2 will use it, if available. Do you use cookies or sessions? You should install it.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_Math__Random__ISAAC__XS__Math__Random__ISAAC__XS__a__and__a_href__https___metacpan_org_module_Crypt__URandom__Crypt__URandom__a_"></a><b><a href="https://metacpan.org/module/Math::Random::ISAAC::XS">Math::Random::ISAAC::XS</a> and <a href="https://metacpan.org/module/Crypt::URandom">Crypt::URandom</a></b> <p>If both of these modules are available, Dancer2 will generate a secure session ID. For security and speed purposes, we recommend installing them.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_Scope__Upper__Scope__Upper__a_"></a><b><a href="https://metacpan.org/module/Scope::Upper">Scope::Upper</a></b> <p>Have you ever noticed that <code>redirect</code>, <code>forward</code>, <code>send_error</code>, and <code>pass</code> return from the route for you? We achieve this by using a module called <a href="https://metacpan.org/module/Return::MultiLevel">Return::MultiLevel</a>. It has a Pure-Perl implementation, but if the module <a href="https://metacpan.org/module/Scope::Upper">Scope::Upper</a> is installed, it will use that instead.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_EV__EV__a___in_case_of__a_href__https___metacpan_org_module_AnyEvent__AnyEvent__a__"></a><b><a href="https://metacpan.org/module/EV">EV</a> (in case of <a href="https://metacpan.org/module/AnyEvent">AnyEvent</a>)</b> <p>Dancer2 has asynchronous support, allowing for asynchronous code and streaming responses. If you are writing an asynchronous web application using <a href="https://metacpan.org/module/AnyEvent">AnyEvent</a> or run on an <a href="https://metacpan.org/module/AnyEvent">AnyEvent</a> server, we recommend you install <a href="https://metacpan.org/module/EV">EV</a>.</p> </li> </ul> <h2><a name="coming_next"></a>Coming next</h2> <p>In the next article, we will explore what kind of server configurations we can apply in order to achieve better performance for our applications.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Implementing i18n in a Dancer application using Plugin::LogReport http://advent.perldancer.org/2016/11 perl http://advent.perldancer.org/2016/11 Sun, 11 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="implementing_i18n_in_a_dancer_application_using_plugin__logreport"></a>Implementing i18n in a Dancer application using Plugin::LogReport</h1> <h2><a name="introduction"></a>Introduction</h2> <p>There are a number of ways to approach the internationalisation of a web application. I'm going to look at a method using <a href="https://metacpan.org/module/Log::Report">Log::Report</a>, which includes very comprehensive translation functionality.</p> <p>More specifically, I will use its Dancer2 plugin, <a href="https://metacpan.org/module/Dancer2::Plugin::LogReport">Dancer2::Plugin::LogReport</a>. If you haven't already, please look at my other article on that.</p> <h2><a name="a_basic_application"></a>A basic application</h2> <p>Let's get started by creating a basic application with some strings that we want translated. We'll look at translating the content of templates later.</p> <pre class="prettyprint"># In your route handler package MyApp; use Dancer2; use Dancer2::Plugin::LogReport 'my-domain'; # domain used to group sets of messages get '/' =&gt; sub { notice "Hello world"; template 'index'; }; # In the index template [% FOREACH message IN session.messages %] &lt;p&gt;[% message.toString %]&lt;/p&gt; [% END %]</pre> <p>By running this application, you should see <code>Hello world</code> on the index page.</p> <h2><a name="translating_strings"></a>Translating strings</h2> <p><a href="https://metacpan.org/module/Log::Report">Log::Report</a> has <a href="https://metacpan.org/module/Log::Report#Language-Translations">a lot of functions to translate strings</a>. We'll touch on 2 of the commonly used ones here.</p> <p>To simply translate a fixed string into another, we can use <code>__</code> (2 underscores):</p> <pre class="prettyprint">notice __"Hello world";</pre> <p>This might look a bit strange, but the 2 underscores are simply a function. You can wrap the text in parentheses if you prefer:</p> <pre class="prettyprint">notice __("Hello world");</pre> <p>Both the parent <a href="https://metacpan.org/module/Log::Report">Log::Report</a> module and its inspiration <a href="https://metacpan.org/module/Locale::TextDomain">Locale::TextDomain</a> encourage use of the functions without parentheses though, as it makes the code a more readable.</p> <p>Note that you can't use single quotes, as <code>__'</code> is interpreted as <code>::</code> by Perl</p> <p>We can also use <code>__x</code>, which is the same as <code>__</code>, except that it allows for variables within the string. For example:</p> <pre class="prettyprint">notice __x"Hello {name}", name =&gt; 'Andy';</pre> <p>This means that when the text is extracted as message IDs, any variable content is conveniently separated. It also allows all sorts of clever things, such as adjusting the text for pluralisation depending on variable conditions, but I won't go into that just yet.</p> <p>So, for now, update your web application accordingly:</p> <pre class="prettyprint">get '/' =&gt; sub { notice __"Hello world"; notice __x"Hello {name}", name =&gt; 'Andy'; template 'index'; };</pre> <p>The beauty of the above approach, is that initially you can just add (very easily and unobtrusively) the translation functions to all your strings. Then, at a later date, you can add the translation framework.</p> <h2><a name="extracting_and_translating_the_strings"></a>Extracting and translating the strings</h2> <p>In order to translate the text in the application, we will need some translation tables. We will produce these below.</p> <h3><a name="extracting_and_creating_po_translation_tables"></a>Extracting and creating PO translation tables</h3> <p>An initial template for the tables can be extracted using <a href="https://metacpan.org/module/xgettext-perl">xgettext-perl</a>. From the base directory of your application run:</p> <pre class="prettyprint">xgettext-perl -p messages --from-code=iso-8859-1 .</pre> <p>This will scan the current directory for appropriate Perl files and create a new directory <code>messages</code> with the strings to be translated as message IDs in a default <code>.po</code> file. For more information on the module used to extract the strings, see <a href="https://metacpan.org/module/Log::Report::Extract::PerlPPI">Log::Report::Extract::PerlPPI</a>. Note that the domain specified in the options for <a href="https://metacpan.org/module/Dancer2::Plugin::LogReport">Dancer2::Plugin::LogReport</a> (or <a href="https://metacpan.org/module/Log::Report">Log::Report</a>) is used within the filename. Domains can be used to group together sets of messages (such as if you want to separate groups of messages for different modules).</p> <p>For the purposes of this exercise, a PO file should have been created containing the 2 message IDs ("Hello world" and "Hello {name}"). From this default PO file, create a specific language file in a new directory for this domain:</p> <pre class="prettyprint">mkdir messages/my-domain/ cp messages/my-domain.utf-8.po messages/my-domain/de_DE.utf8.po</pre> <p>Now edit the file, inserting the translation text into the existing lines (the "fuzzy" flag can be removed to indicate that the text has been translated):</p> <pre class="prettyprint">#: ./lib/Advent.pm:11 #, msgid "Hello world" msgstr "Hallo Welt" #: ./lib/Advent.pm:12 #, msgid "Hello {name}" msgstr "Hallo {name}"</pre> <h3><a name="adding_a_translator_to_your_application"></a>Adding a translator to your application</h3> <p>To add a translator, add the following code to your route handler:</p> <pre class="prettyprint">use Log::Report::Translator::POT; (textdomain 'my-domain')-&gt;configure( translator =&gt; Log::Report::Translator::POT-&gt;new( lexicon =&gt; 'messages' # Directory of the PO files ) );</pre> <p>Now run your application, this time specifying another language:</p> <pre class="prettyprint">LC_MESSAGES=de_DE.utf8 perl bin/app.pl</pre> <p>When you visit the index page, the text should now have been appropriately translated.</p> <h2><a name="translating_text_within_templates"></a>Translating text within templates</h2> <p>Translating text within templates is very similar to translating strings within the application, except that being a template, the translation functions aren't quite so readily available. For the purposes of this example, I'm going to assume that you're using <code>Template::Toolkit</code>.</p> <p>As we don't have a readily available translating function, we'll do things the other way around this time, and start by providing a translating function to each template. Add the following to your route handler:</p> <pre class="prettyprint">sub translate { my $msg = Log::Report::Message-&gt;fromTemplateToolkit('tt-domain', @_); $msg-&gt;toString; } hook before_template =&gt; sub { shift-&gt;{loc} = \&amp;translate; };</pre> <p>The above code adds a subroutine <code>loc</code> that can be called from within each template. Note that we are using a different domain; this is good practive in order to keep the sets of messages completely separate, but it's also possible to use the same domain if you prefer.</p> <p>As a simple example, add the following to your <code>index</code> template:</p> <pre class="prettyprint">[% loc("We are dancing") %]</pre> <p>(See <a href="https://metacpan.org/module/Log::Report::Extract::Template">Log::Report::Extract::Template</a> for more powerful examples.)</p> <p>Again, we'll need to extract the message IDs for translation. This can be done in a similar manner to last time, but this time specifying template files:</p> <pre class="prettyprint">xgettext-perl -p messages --from-code=iso-8859-1 --template TT2-loc --domain tt-domain .</pre> <p>Note that if you are using the same domain, then this will remove message strings from your original extractions (unless the same messages appear in the template files). To prevent this, you can you use the <code>--no-cleanup</code> option, in which case the previous messages will be commented out. As per the comment above, it's best to use separate domains for this reason.</p> <p>Repeat the previous process, copying the default translation to a German file in the new domain, and add the translation:</p> <pre class="prettyprint">mkdir messages/tt-domain/ cp messages/tt-domain.utf-8.po messages/tt-domain/de_DE.utf8.po msgid "We are dancing" msgstr "Wir tanzen"</pre> <p>Finally add a new translator for the new domain:</p> <pre class="prettyprint">(textdomain 'tt-domain')-&gt;configure( translator =&gt; Log::Report::Translator::POT-&gt;new( lexicon =&gt; 'messages' # Directory of the PO files ) );</pre> <p>Re-run the application, and both the previous string as well as new template text should be translated.</p> <h2><a name="handling_plurals"></a>Handling plurals</h2> <p><a href="https://metacpan.org/module/Log::Report">Log::Report</a> has several translating functions, all detailed <a href="https://metacpan.org/module/Log::Report#Language-Translations">in the documentation</a>. To give an example, here's code that handles pluralisation:</p> <pre class="prettyprint">my @files = ("File") x (int(rand(2))+1); notice __xn"Saved one file", "Saved {_count} files", @files;</pre> <h2><a name="author"></a>Author</h2> <p>This article has been written by Andy Beverley for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> </div> Exception handling, error logging and user messages made easy http://advent.perldancer.org/2016/10 perl http://advent.perldancer.org/2016/10 Sat, 10 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="exception_handling__error_logging_and_user_messages_made_easy"></a>Exception handling, error logging and user messages made easy</h1> <h2><a name="introduction"></a>Introduction</h2> <p>Have you ever experienced any of the following when writing your Dancer application?</p> <ul> <li><a name="item_Found_that_handling_user_errors_involved_writing_a_lot_of_code"></a><b>Found that handling user errors involved writing a lot of code</b> </li> <li><a name="item_Wanted_to_log_messages_from_a_module__without_that_module_depending_on_Dancer2"></a><b>Wanted to log messages from a module, without that module depending on Dancer2</b> </li> <li><a name="item_Wanted_flexibility_on_sending_messages_to_the_user__to_the_system__or_both"></a><b>Wanted flexibility on sending messages to the user, to the system, or both</b> </li> <li><a name="item_Found_yourself_writing_the_same_code_in_every_application_in_order_to_send_messages_to_a_template"></a><b>Found yourself writing the same code in every application in order to send messages to a template</b> </li> <li><a name="item_Wanted_a_clean_way_to_handle_500_errors__whilst_getting_notified_as_the_system_administrator"></a><b>Wanted a clean way to handle 500 errors, whilst getting notified as the system administrator</b> </li> </ul> <p><a href="https://metacpan.org/module/Dancer2::Plugin::LogReport">Dancer2::Plugin::LogReport</a> combined with <a href="https://metacpan.org/module/Dancer2::Logger::LogReport">Dancer2::Logger::LogReport</a> are designed to do all of the above, and more. Although the 2 modules can be used separately, it's recommended to use them both together.</p> <h2><a name="getting_started"></a>Getting Started</h2> <p>Let's get started by adding the 2 modules to a Dancer2 app:</p> <pre class="prettyprint"># In your route handler package MyApp; use Dancer2; use Log::Report (); use Dancer2::Plugin::LogReport; # In your config logger: LogReport</pre> <p>So, what does this give us as standard? Let's have a look:</p> <ul> <li><a name="item_Default_console_logging"></a><b>Default console logging</b> <p>By default, the logger will continue logging to STDERR. The formatting will be different, but that can be configured later. It's worth noting that by default debug messages will not be shown, as the default verbosity is a higher threshold. The threshold can be changed, see the <a href="https://metacpan.org/module//Dispatchers">/Dispatchers</a> section below.</p> </li> <li><a name="item_Additional_logging_keywords"></a><b>Additional logging keywords</b> <p>We have some additional logging levels. Given that Dancer already provides us with 5, you might think this unnecessary. The extra levels give us a really handy feature though: we can differentiate between messages that we would normally want to send to the user, and messages that we would normally want sent to the system. For example, we can now do:</p> <pre class="prettyprint"># Send a routine notice to the end user notice "Hey user, I thought you might want to know this" # Tell the user something has been successful success "Your changes have been saved" # Warn the user (not fatal) mistake "You may not have wanted to use that setting" # Tell the user an error has happened (fatal) error "You can't use that option" # Bork (also fatal) panic "This really should not happen in our app" # Log a debug message trace "Started function foo"</pre> <p>But where do these messages go? Read on.</p> </li> <li><a name="item_Messages_are_saved_in_the_session"></a><b>Messages are saved in the session</b> <p>Messages are automatically saved in the session, in a key called <code>messages</code>. By default, not all messages are saved, as you probably don't want the user seeing your debug messages. The default configuration of which messages are sent should work for most people, but can be configured if required.</p> <p>To display the messages, you can do something like this in your layout template:</p> <pre class="prettyprint">[% FOREACH msg IN session.messages %] &lt;p&gt;[% msg.toString | html_entity %]&lt;/p&gt; [% END %]</pre> <p>Each message is an object, and can be stringified as above.</p> <p>The object includes a function to automatically select a sensible Bootstrap color, so if you're using Bootstrap in your application, you could do this:</p> <pre class="prettyprint">[% FOREACH msg IN session.messages %] &lt;div class="alert alert-[% msg.bootstrap_color %]"&gt; [% msg.toString | html_entity %] &lt;/div&gt; [% END %]</pre> </li> <li><a name="item_Using_the_message_keywords_without_using__code_Dancer2__code_"></a><b>Using the message keywords without using <code>Dancer2</code></b> <p>In any other module, you can now include <code>Log::Report</code> and use the same keywords/functions to send messages to your application. The one exception is the use of the special <code>success</code> keyword, which is specific to the plugin (although there is a workaround for that if needed).</p> </li> <li><a name="item_Clean_exception_handling"></a><b>Clean exception handling</b> <p>The module will also, by default, handle any application exceptions cleanly. Instead of sending a 500 error, it will forward to an appropriate page, with the message rendered in the template as above. More on this to follow later.</p> <p>If the application is running with <code>show_errors</code> enabled, then the full error will be sent in the message. If <code>show_errors</code> is disabled (such as in a production environment), a generic error message is shown and the full error will have been sent to the console, or whichever backend is configured.</p> </li> </ul> <p>In summary, by including a couple of modules, we can easily send messages to a template, and we are handling application exceptions in a user-friendly manner, whilst still capturing the full error information.</p> <h2><a name="handling_user_errors_easily_and_cleanly"></a>Handling user errors easily and cleanly</h2> <p>Handling user errors can be a bit boring and tedious. We'll talk about a way to do so that requires very little code.</p> <p>First, let's have a look at how we might normally do it. I won't go into this in any detail, but you will probably recognise the concept. Maybe something like this:</p> <pre class="prettyprint">package MyApp; post '/settings' =&gt; sub { my $message; try { MyApp::Settings-&gt;update($settings); $message = "Settings updated successfully"; } catch { $message = $@; }; # Do something with $message ... }; package MyApp::Settings; sub update { ... die "Invalid email address" unless ... ... }</pre> <p>That works fine to a degree, but the code can easily get more verbose than that, and even that alone can get a little tedious to keep typing.</p> <p>How would we do that with <a href="https://metacpan.org/module/Dancer2::Plugin::LogReport">Dancer2::Plugin::LogReport</a>?</p> <pre class="prettyprint">package MyApp; post '/settings' =&gt; sub { if (process sub{ MyApp::Settings::update($settings) }) { success "Settings updated successfully"; } # No further code needed - all messages already handled }; package MyApp::Settings; use Log::Report; sub update { ... error "Invalid email address" unless ... ... }</pre> <p>That's it. But what if it wasn't successful? Well, the module handles all that for you. The <code>error</code> function in the module is fatal just like <code>die</code>, but as we showed above, its text will have automatically been sent to the template for display to the user.</p> <p>If you use <code>error</code> outside of <code>process</code>, then it is still fatal and the text is still sent to the template, but it's not handled quite as cleanly: the user is forwarded back to the same page if it was a <code>POST</code> request, forwarded to <code>/</code> if it was a <code>GET</code> request, or fails uncleanly if it was already a <code>GET</code> request to <code>'/'</code>.</p> <p>As an aside, you would probably want to use the same route handler for both <b>GET</b> and <b>POST</b>. If the <b>POST</b> is unsuccessful, the error is caught, and the page will behave as a <b>GET</b> request (but with the error text rendered).</p> <h3><a name="a_note_on_differentiating_between_expected_and_unexpected_exceptions"></a>A note on differentiating between expected and unexpected exceptions</h3> <p>If a fatal error occurs that did not originate as a <a href="https://metacpan.org/module/Log::Report">Log::Report</a> message, then at some point it has to be translated into its <a href="https://metacpan.org/module/Log::Report">Log::Report</a> equivalent. By default in <a href="https://metacpan.org/module/Log::Report">Log::Report</a> there is a bit of guesswork that goes into this (to try and classify exceptions aimed at users and developers of accordingly). However, given that it is very unlikely that in a web application you would want to report the exact exception message to an end user, within the latest versions of this plugin all fatal exceptions that occur are classified as <code>PANIC</code>. This means that you can handle them as system errors and deal with the accordingly. Any unexpected exceptions (such as calling methods on undefined values) will then be handled cleanly within your web application.</p> <h2><a name="dispatchers"></a>Dispatchers</h2> <p>While you can use everything so far the way I have demonstrated, there is added value in understanding the concept of <a href="https://metacpan.org/module/Log::Report">Log::Report</a> dispatchers. A dispatcher is something that processes a message, similar to a Dancer logging engine. You can have as many dispatchers as you want, and there are several types available (<code>Log::Report::Dispatcher::*</code>). By default, a <code>PERL</code> dispatcher is created for sending messages to STDERR, and a special <code>Callback</code> dispatcher is used for sending the messages to the template. Dispatchers are added using the <a href="https://metacpan.org/module/Dancer2::Logger::LogReport">Dancer2::Logger::LogReport</a> configuration.</p> <p>The configuration of each dispatcher defines what messages it outputs. You might want one dispatcher to show all messages, but another to only display messages above a certain threshold. The <code>mode</code> of a dispatcher defines what messages are shown. The default <code>mode</code> is <code>NORMAL</code>, which only shows messages at the level of <code>NOTICE</code> and above. You can change the mode to <code>VERBOSE</code>, <code>ASSERT</code> or <code>DEBUG</code> to get an increasing level of messages. If you don't specifiy a mode for a dispatcher, it will take the "global" value. The default global value is <code>NORMAL</code>. The global value can be changed when loading the module:</p> <pre class="prettyprint">use Dancer2::Plugin::LogReport mode =&gt; 'DEBUG';</pre> <p>If you want finer control on what messages a dispatcher processes, you can also configure the <code>accept</code> parameter. A full dispatcher configuration might look like this:</p> <pre class="prettyprint">engines: logger: LogReport: dispatchers: default: # Name. This one overrides the default dispatcher type: PERL mode: NORMAL accept: FAILURE- # Only FAILURE messages and above syslog # Additional dispatcher called syslog type: SYSLOG identity: myapp facility: local0 flags: "pid ndelay nowait" mode: DEBUG</pre> <p>Dispatchers can also be used to format messages.</p> <h2><a name="there_is_a_lot_more"></a>There is a lot more</h2> <p>The above is just a flavour of the common and easy stuff you might like to do. <code>Log::Report</code> itself is way, way more powerful than that though. There are even more advanced topic, such as:</p> <ul> <li><a name="item_Add_messages_to_a_class"></a><b>Add messages to a class</b> <p>You can add messages to a particular type of class. I use this to tag some as HTML content. By default, I HTML-encode all messages in a template, this class can be used to bypass that.</p> </li> <li><a name="item_Use_syslog_for_email_notifications"></a><b>Use syslog for email notifications</b> <p>I use a <a href="https://metacpan.org/module/Log::Report::Dispatcher::Syslog">Syslog</a> dispatcher, and configure <a href="http://man7.org/linux/man-pages/man8/rsyslogd.8.html">rsyslogd</a> to email me on any message above a certain severity. This means that I am normally fixing an application error before it has been reported by the user.</p> </li> <li><a name="item_Translate_message_into_other_languages"></a><b>Translate message into other languages</b> <p>You can translate your messages into other languages using <a href="https://metacpan.org/module/Log::Report::Translator">Log::Report::Translator</a>. Importantly, you can do this by dispatcher, so you can have user messages in the template translated, but system messages in the native language. Stay tuned for a follow-up Advent article for details of how to do this.</p> </li> <li><a name="item_DBIC_logging"></a><b>DBIC logging</b> <p>You can use <a href="https://metacpan.org/module/Log::Report::DBIC::Profiler">Log::Report::DBIC::Profiler</a> to profile DBIC queries in your application.</p> </li> </ul> <h2><a name="finally___"></a>Finally...</h2> <p>I did a talk on the above at LPW: <a href="https://www.youtube.com/watch?v=S1eW5tE967c">https://www.youtube.com/watch?v=S1eW5tE967c</a></p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Andy Beverley for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> </div> New parameters keywords http://advent.perldancer.org/2016/9 perl http://advent.perldancer.org/2016/9 Fri, 9 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="new_parameters_keywords"></a>New parameters keywords</h1> <p>A common problem and difficulty with web programming is incorrect parameters handling. We usually don't spend much time thinking about it, until things break. Dancer2 has added special keywords to help you out with this.</p> <h2><a name="the_problem"></a>The problem</h2> <p>First, let's clarify what is the issue we come across.</p> <p>When handling parameters, we make several assumptions. Our first assumption is that all parameters are one big pile of information. Parameters come in two forms, and Dancer2's route spec adds another: <b>query</b>, <b>body</b>, and <b>route</b>.</p> <p>When we call <code>params</code>, we retrieve a parameter from the collection of all of these parameter values put together, which could be clobbered values, if they are provided multiple times:</p> <pre class="prettyprint">post '/' =&gt; sub { # is this from a query or from the body? my $name = params-&gt;{'name'}; };</pre> <p>We can control the source of the parameter values as the parameter to <code>params</code>:</p> <pre class="prettyprint">get '/' =&gt; sub { # positively from the query my $name = params('query')-&gt;{'name'}; };</pre> <p>A much bigger mistake we make is assuming that parameters are provided as single values. Thus, we simply retrieve the parameter value:</p> <pre class="prettyprint">post '/upload' =&gt; sub { my $filename = params('body')-&gt;{'filename'}; };</pre> <p>If you've been bitten before, this is already askew to you. What happens if the <b>name</b> parameter was provided twice? Of course, we can write appropriate code for this as well:</p> <pre class="prettyprint">post '/upload' =&gt; sub { my @filenames = @{ params('body')-&gt;{'filename'} }; };</pre> <p>However, we do not know how many were provided. It is possible that our form only contains a single parameter entry but a user has maliciously has sent two or more, or misused our API by mistake. We are then forced to verify this by writing code that checks for both scenarios:</p> <pre class="prettyprint">post '/upload' =&gt; sub { my @filenames; if ( ref params('body')-&gt;{'filename'} ) { if ( ref params('body')-&gt;{'filename'} eq 'ARRAY' ) { @filenames = ( params('body')-&gt;{'filename'} ); } else { # Will not happen } } else { @filenames = @{ params('body')-&gt;{'filename'} }; } };</pre> <p>That is indeed a lot to take in. We also end up with an array of filenames, even if we only care about one. Let's write more succinct and accurate code for this:</p> <pre class="prettyprint">post '/upload' =&gt; sub { # if we assumed only one filename my $filename = ref params('body')-&gt;{'filename'} ? params('body')-&gt;{'filename'}-&gt;[-1] # assuming last is ok : params('body')-&gt;{'filename'}; # if we assumed multiple possible filenames my @filenames = ref params('body')-&gt;{'filename'} ? @{ params('body')-&gt;{'filename'} } : ( params('body')-&gt;{'filename'} ); };</pre> <h2><a name="the_solution"></a>The solution</h2> <p>We have introduced three new keywords to help you handle both of these issues easily: <code>route_parameters</code>, <code>query_parameters</code>, and <code>body_parameters</code>. Let's explore them.</p> <p>Firstly, you may notice that they already provide a clear indication of the source of the parameters using their name. This is to be clear and declarative on what you want to retrieve, instead of assuming the jumble clobbered combination would be fine.</p> <p>Secondly, each one provides you with a <a href="https://metacpan.org/module/Hash::MultiValue">Hash::MultiValue</a> object which can either be used as a hash, or as an object that can retrieve the amount of values declaratively.</p> <p>If we would like to make sure we always have a single value for a parameter, we simply either call it as a hash key or using the appropriate method:</p> <pre class="prettyprint">post '/upload' =&gt; sub { my $filename = body_parameters-&gt;get('filename'); # or my $filename = body_parameters-&gt;{'filename'}; };</pre> <p>If a single filename is provided, this will be the value. If multiple values are sent by the user (either on purpose or by mistake), you will always receive the last one. Does it matter? No, since the user was supposed to only send one anyway.</p> <p>But what happens when we want multiple values? That's trickier because we might still only get one value, but we can <i>possibly</i> get multiple ones. With these new keywords, it's just as simple:</p> <pre class="prettyprint">post '/upload' =&gt; sub { # we support multiple filenames # maybe none, maybe one, maybe more my @filenames = body_parameters-&gt;get_all('filename'); };</pre> <p>This will always return multiple values, no matter how many were actually sent.</p> <p>You can, of course, use all of them at once, despite them usually not being combined in HTTP:</p> <pre class="prettyprint">post '/upload/:entity' =&gt; sub { my $entity = route_parameters-&gt;{'entity'}; my $user = query_parameters-&gt;{'user'}; my @filenames = body_parameters-&gt;get_all('filename'); ... };</pre> <p>We wholeheartedly recommend using these new keywords instead of calling the other keywords such as <code>param</code> and <code>params</code>. They make your code clearer and smarter.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Automatic Restarts http://advent.perldancer.org/2016/8 perl http://advent.perldancer.org/2016/8 Thu, 8 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="automatic_restarts"></a>Automatic Restarts</h1> <p>A common annoyance many of us share when developing web applications is restarting our web application every time we edit files.</p> <p>While we do not need to restart our web server when changing image, JavaScript, CSS, or template files, we still require it when changing our application code.</p> <p>Dancer 1 had an option to reload the application on file changes but it proved brittle and in some cases caused more annoyance than it prevented.</p> <p>There are several ways to handle this nowadays. Let's go through them.</p> <h2><a name="_code_plack__middleware__refresh__code_"></a><code>Plack::Middleware::Refresh</code></h2> <p>The <a href="https://metacpan.org/module/Plack::Middleware::Refresh">Plack::Middleware::Refresh</a> module allows us to refresh your application and all of its modules.</p> <p>All we need to do is load this middleware in our handler:</p> <pre class="prettyprint"># app.psgi use MyApp; use Plack::Builder; builder { enable 'Refresh'; MyApp-&gt;to_app; };</pre> <p>However, this will turn it on all the time under every environment. We can control that by loading it only if we are in the development environment:</p> <pre class="prettyprint"># app.psgi use MyApp; use Plack::Builder; builder { if ( $ENV{'PLACK_ENV'} eq 'development' ) { enable 'Refresh'; } MyApp-&gt;to_app; };</pre> <p>However, this requires changing our handler. This will affect all other developers as well, and might cause restarts while we're still working on multiple files and cannot control whether it will restart.</p> <p>There are other solutions that are likely to yield more flexibility.</p> <h2><a name="_code_plackup__r__code__or__code_plackup__r__code_"></a><code>plackup -r</code> or <code>plackup -R</code></h2> <p><a href="https://metacpan.org/module/Plack">Plack</a> comes with a built-in command to start a web server for our web application. It doesn't start all web servers but it works for Perl-based web servers such as <a href="https://metacpan.org/module/Starman">Starman</a> or <a href="https://metacpan.org/module/Gazelle">Gazelle</a>.</p> <pre class="prettyprint"># start web server, restarting when a file in lib/ changes plackup -r bin/app.psgi</pre> <p>We may have renamed the <i>lib</i> directory. In this case, we will need to use <code>-R</code> instead:</p> <pre class="prettyprint"># assuming we lib/ to routes/ plackup -R bin,routes bin/app.psgi</pre> <p>This will monitor both <i>bin</i> and <i>routes</i> so you can update your code or your handler and the web server will restart automatically.</p> <p>You can also monitor additional directories. Imagine having having a templating system that uses compiled templates. You generated the compiled ones during a start of the application. The original ones would be stored in <i>templates</i> and compiled and stored in <i>views</i>.</p> <pre class="prettyprint">plackup -R routes,templates bin/app.psgi</pre> <p>Any change to <i>routes</i> directory or to <i>templates</i> will force a restart, compiling your templates again and providing you with fresh code.</p> <h2><a name="_code_shotgun__code_"></a><code>Shotgun</code></h2> <p>As a last resort, when the above approach aren't convenient or do not perform well, you can use the <code>Shotgun</code> loader from <a href="https://metacpan.org/module/Plack::Loader::Shotgun">Plack::Loader::Shotgun</a>.</p> <p>It's quite simple and you can load it by calling it with <code>-L</code>:</p> <pre class="prettyprint">plackup -L Shotgun bin/app.psgi</pre> <p>Instead of watching and restarting, this loader simply forks and runs each request with its own process. If you are loading heavy modules and would like to speed it up, you can do so with <code>-M</code>:</p> <pre class="prettyprint">plackup -MMoose -MDBIx::Class -L Shotgun bin/app.psgi</pre> <h2><a name="author"></a>Author</h2> <p>This article has been written by Sawyer X for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div> Medium-Scale Dancer, Part 5: REST APIs and JSON http://advent.perldancer.org/2016/7 perl http://advent.perldancer.org/2016/7 Wed, 7 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="medium_scale_dancer__part_5__rest_apis_and_json"></a>Medium-Scale Dancer, Part 5: REST APIs and JSON</h1> <p>In previous parts of <a href="https://metacpan.org/module//2016/3">this article series</a>, I defined each route handler as a one-liner, like so:</p> <pre class="prettyprint">prefix '/mf' =&gt; sub { get '' =&gt; \&amp;retrieve; prefix '/sf' =&gt; sub { get '' =&gt; \&amp;_get; post '' =&gt; \&amp;_post; put '' =&gt; \&amp;_put; del '/:id' =&gt; \&amp;_del; }; };</pre> <p>This is very much on purpose, despite the fact that Dancer lets you define all of the code for each route handler within an anonymous code reference (e.g. <code>sub { ... }</code>) block. What do we get by moving those functions elsewhere, and what do we gain that makes it worth tolerating the ugly <code>\&amp;</code> syntax?</p> <p>The first benefit we get from doing that is that named subroutines make stack traces easier to read.</p> <p>Second &#x2014; and far more important to our purposes here in this article series &#x2014; defining your routes this way makes the URL structure of the web app explicit in the code. You are more likely to notice design problems by studying the indented route definitions in the Perl code than by looking at your app's <code>views</code> subdirectory, even if it is structured exactly the same way as recommended in an earlier article in this series, simply because it is atypical to be looking at a full tree view of a filesystem. You end up with a kind of tunnel vision when looking at one directory at a time.</p> <p>This practice of defining Dancer route handlers as one-liners solves that. It ensures that every time you adjust the route handlers for your site, you're doing so while looking at the neighboring routes; you will be defining new routes in context, not independently. This counteracts the entropic forces that result in API design drift because it implicitly encourages you to define new routes that fit logically into the scheme you defined previously. Without this extra Perl function call layer, the route definitions are visually broken up, so that you cannot see the whole design on a single screen. The resulting URL scheme can turn into a mess, as developers hack on the app over the course of years.</p> <p>This is also why I have carefully lined up the blocks and <a href="https://en.wikipedia.org/wiki/Fat_comma">fat commas</a> in the route definitions: I want patterns in the URL scheme to jump out at me. Left-justifying everything obscures these patterns.</p> <p>Now you may be asking, why does all this matter?</p> <p>The reason is simple: When you make patterns in the URL scheme graphically apparent, you may discover some previously hidden practical value that was just sitting there waiting to be exploited. It works for the same reason that seeing a plot for a numeric data set for the first time sometimes creates a clear call to action.</p> <p>It turns out that the example route scheme we've been defining throughout this article series includes a web API; it's just been sitting there, waiting to be discovered. With a bit of polishing, it might even turn into a proper <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> API. Let's try.</p> <p>Look back up at that route definition block above. What does it remind you of? If you said <a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a>, go to the head of the class.</p> <p>Now, HTTP verbs do not correspond directly to CRUD because HTTP was not designed to be a CRUD API. There are competing design philosophies when it comes to mapping HTTP verbs to the CRUD model of persistent data storage.</p> <p>I prefer this mapping:</p> <pre class="prettyprint"> DB term | HTTP verb +------------+---------- | C = create | POST | R = read | GET | U = update | PUT | D = delete | DELETE</pre> <p>The R = <code>GET</code> and D = <code>DELETE</code> rules are obvious, but it may not be clear to you why the other two rules are correct.</p> <p><a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">The HTTP spec</a> defines <code>POST</code> and <code>PUT</code> so that they're nearly interchangeable, which is how we ended up with competing REST/CRUD API design philosophies.</p> <p>Some web API designers like to use <code>POST</code> for both create and update operations since you can distinguish the cases based on whether the HTTP request contains a database row ID: if so, it's a request to update an existing record, else it's a record creation request.</p> <p>That justification is fine in a web framework that defines the URL scheme in the file system, such as PHP, ASP, or JSP since it is normal to handle all four verbs in a single file in that sort of web framework. In Dancer, my preferred scheme works better since it defines one route per CRUD operation.</p> <p>Although the HTTP spec defines <code>PUT</code> and <code>POST</code> as partially interchangeable, you must not swap the <code>PUT</code> and <code>POST</code> verbs from the way I've defined them above. The HTTP spec says <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1"><code>PUT</code> is idempotent</a>, meaning that the browser is allowed to cache <code>PUT</code> requests, suppressing subsequent identical calls if the request parameters do not change. In CRUD terms, this means that if you define "create" in terms of <code>PUT</code>, the browser might not let you create two records with identical contents but different IDs, which means you risk losing data. The HTTP spec does not allow browsers to assume that identical <code>POST</code> calls are idempotent, however, so we use that verb for CRUD's create operation, leaving <code>PUT</code> = update.</p> <p>That's enough design philosophy; how does all that affect our Dancer code? We might decide that since we've almost got a REST API here that we might want to push it the rest of the way.</p> <p>Let's move the CRUD-like route handlers in <code>lib/App/MajorFeature/SubFeature.pm</code> to <code>lib/App/API/MajorFeature/SubFeature.pm</code>. We can also refine the programming interface a bit:</p> <pre class="prettyprint">prefix '/api' =&gt; sub { prefix '/mf' =&gt; sub { prefix '/sf' =&gt; sub { post '' =&gt; \&amp;_post; get '' =&gt; \&amp;_get; put '/:id' =&gt; \&amp;_put; del '/:id' =&gt; \&amp;_del; }; }; };</pre> <p>My choice to use leading underscores in these module-internal route handler function names lets us parallel the Dancer DSL keyword naming scheme.</p> <p>You might instead prefer to make the HTTP-to-CRUD mapping more explicit:</p> <pre class="prettyprint">prefix '/api' =&gt; sub { prefix '/mf' =&gt; sub { prefix '/sf' =&gt; sub { post '' =&gt; \&amp;_create; get '' =&gt; \&amp;_read; put '/:id' =&gt; \&amp;_update; del '/:id' =&gt; \&amp;_delete; }; }; };</pre> <p>As in the previous article in this series, the leading underscore convention saves us some aggravation here since <code>delete</code> is a Perl keyword, and <code>read</code> is a core Perl function.</p> <p>The only other thing to change here is that REST APIs normally return JSON or XML. I prefer JSON since that's directly usable by the JavaScript code that made the Ajax call to one of these APIs. One of the best features of Dancer is that automatic JSON encoding is built right in.</p> <p>First, enable the feature by adding this to your <code>config.yml</code> file:</p> <pre class="prettyprint">serializer: "JSON"</pre> <p>That lets us write the <code>_create()</code> function referenced above as:</p> <pre class="prettyprint">sub _create { my $params = request-&gt;params; my $db = get_db_conn; if ($db-&gt;create_something($params-&gt;{arg1}, $params-&gt;{arg2})) { return { success =&gt; JSON::true, id =&gt; $db-&gt;last_insert_id(), }; } else { return { success =&gt; JSON::false, error =&gt; 'failed to create record: ' . $db-&gt;last_error(), }; } }</pre> <p>By telling Dancer that we want all routes to return JSON unless explicitly told otherwise, we can simply return Perl data structures and have Dancer translate them into JSON form for us. It will also automatically set the response's HTTP <code>Content-Type</code> header to <code>application/json</code>. Parsing and using that reply on the client side in JavaScript is therefore trivial. Many web frameworks can consume such APIs directly, such as jQuery via <a href="https://api.jquery.com/jQuery.getJSON/"><code>$.getJSON()</code></a>.</p> <p>Doing so does mean that your existing HTML-returning route handlers have to be explicitly marked to return HTML instead:</p> <pre class="prettyprint">get '/some/html/returning/route' =&gt; sub { send_as html =&gt; template '/some/template' =&gt; { some =&gt; 'parameters', }; };</pre> <h2><a name="returning_the_same_data_in_both_html_and_json_forms"></a>Returning the Same Data in Both HTML and JSON Forms</h2> <p>You might now be asking why you would arrange things as above, where the default serializer is JSON and HTML-returning routes have to be explicitly marked. If your application returns HTML more often than JSON, this may seem backwards. Wouldn't it be simpler to leave the default serializer unset, so that <code>template</code> calls and such return normally, and mark the JSON-returning API route handlers explicitly instead via <code>send_as JSON =&gt; ...</code>?</p> <p>You could indeed do that, but then you lose a nice side benefit of this arrangement: it makes it easy to define parallel route handlers for returning HTML-rendered versions of APIs that return raw JSON data.</p> <p>Consider this addition to the route handlers defined above:</p> <pre class="prettyprint">package App::Parts::MajorFeature::SubFeature use Dancer2 appname =&gt; 'App'; sub _get { send_as html =&gt; template 'parts/mf/sf' =&gt; { content =&gt; App::API::MajorFeature::SubFeature::_get(), } } prefix '/parts' =&gt; sub { prefix '/mf' =&gt; sub { prefix '/sf' =&gt; sub { get '' =&gt; \&amp;_get; }; }; };</pre> <p>Briefly, what this does is define a <code>/parts</code> route hierarchy that is parallel to the <code>/api</code> hierarchy, with the former implemented in terms of the latter. That is, the application's API returns JSON, and the applications "parts" subsystem returns HTML renditions of the same data returned by the JSON API. This works because the API route handlers are defined to return raw Perl data structures, which we can consume directly from other route handlers as above, or let Dancer render them to JSON when those route handlers are called by a web client.</p> <p>While you could consume these HTML fragments ("parts") via Ajax, you can also save an HTTP round trip by textually including them into complete web pages assembled by Dancer's template mechanism:</p> <pre class="prettyprint">package App::MajorFeature::SubFeature use Dancer2 appname =&gt; 'App'; sub _get { send_as html =&gt; template 'mf/sf' =&gt; { some =&gt; 'parameters', go =&gt; 'here', part =&gt; App::Parts::MajorFeature::SubFeature::_get(), } } prefix '/mf' =&gt; sub { prefix '/sf' =&gt; sub { get '' =&gt; \&amp;_get; }; };</pre> <p>The <code>/views/mf/sf.tt</code> template can then reference <code>part</code> to insert the HTML fragment into the larger web page, without duplicating the HTML code for that fragment.</p> <p>This gives us three different ways to get the same data: as part of a complete web page (<code>GET /mf/sf</code>), as an HTML fragment that we can insert into an existing web page via Ajax on the browser side or textual inclusion on the Dancer side (<code>GET /parts/mf/sf</code>), and as raw JSON data that we could process on the browser side (<code>GET /api/mf/sf</code>).</p> <p>This layered design pattern has two additional benefits besides avoiding violations of the <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY principle</a>:</p> <p>First, textually including an HTML rendering of the raw data on the server side as part of the initial HTTP page load saves an HTTP round trip over the common alternative design, where the server simply returns an empty HTML container which must be filled by JavaScript code with a subsequent JavaScript Ajax call. HTTP round-trips are usually expensive enough to add human-scale amounts of delay to your web app's response time, so any time you spend to remove unnecessary round-trips usually pays immediate tangible benefits.</p> <p>Second, this design ensures that your web app returns an initial HTML view of the data even to clients not running JavaScript. Even if you can ensure that your normal web users will run JavaScript, you may gain some SEO benefit by returning an HTML form of your web app's dynamic content to web spiders that refuse to run embedded and referenced JavaScript code.</p> <p>This article series concludes with a scheme for <a href="https://metacpan.org/module//2016/8">hot code reloading</a>, a very useful feature in any Dancer app, but especially helpful as your app grows larger.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Warren Young for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>&#xa9; 2015, 2016 by Educational Technology Resources, licensed under <a href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0</a></p> </div> Medium-Scale Dancer, Part 4: Front-End Matters http://advent.perldancer.org/2016/6 perl http://advent.perldancer.org/2016/6 Tue, 6 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="medium_scale_dancer__part_4__front_end_matters"></a>Medium-Scale Dancer, Part 4: Front-End Matters</h1> <p>This will be a short article because the way you write your client-side JavaScript code and serve it to your users has almost nothing to do with Dancer. Nevertheless, there are a few things we can say here that tie into the prior articles in <a href="http://advent.perldancer.org/2016/3">this series</a>.</p> <h2><a name="consolidate_javascript_files"></a>Consolidate JavaScript Files</h2> <p>Because each HTTP round-trip over the Internet takes <a href="https://en.wikipedia.org/wiki/Mental_chronometry">human-scale time</a> &#x2014; tens to hundreds of milliseconds &#x2014; an important part of making a fast web site is to consolidate your JavaScript code into as few files as possible.</p> <p>Ideally, you will end up with just one JavaScript file, perhaps called <code>public/javascripts/app.js</code>.</p> <p>This seems to go against the whole thrust of this article series so far, which has been about factoring monolithic structures into smaller, purpose-focused ones. But, there's a trick that lets you have your cake and eat it, too: tools like <a href="http://requirejs.org/">RequireJS</a> allow you to "compile" multiple JavaScript files down to a single file. Coupled with <a href="https://en.wikipedia.org/wiki/Minification_(programming)">minification</a>, <a href="https://en.wikipedia.org/wiki/HTTP_compression">compression</a>, and aggressive <a href="https://en.wikipedia.org/wiki/Web_cache">caching</a> rules in your front-end web server, your app will feel a lot snappier to your users, even though the size of the web app on disk is no smaller than before.</p> <p>You might not choose to compile all of your JavaScript down to a single file. If it makes more sense for your purposes to use several files, I suggest that you name those files after the top-level URL that uses it. For example, the <code>/mf</code> URLs we've been using in examples so far should be served by a <code>public/javascripts/mf.js</code> file. You might still wish to develop <code>mf.js</code> in several different purpose-driven JS files, compiled down to <code>mf.js</code> by RequireJS or a similar tool.</p> <h2><a name="serve_static_assets_via_a_front_end_reverse_proxy_server"></a>Serve Static Assets Via a Front-End Reverse Proxy Server</h2> <p>The <a href="https://metacpan.org/pod/distribution/Dancer2/lib/Dancer2/Manual/Deployment.pod">Dancer2 Deployment Guide</a> recommends running your app behind a front-end reverse proxy server such as nginx or Apache's <code>mod_proxy</code>. I strongly encourage you to do this, even in development.</p> <p>The server setup given in the deployment guide will cause the front-end proxy server to handle all requests for static content files itself, passing URLs down to Dancer only when it cannot find a static asset with the requested name. This takes a huge load off of Dancer, which, you must remember, is dynamic Perl code, so it will naturally be slower than the highly optimized C code in the proxy server.</p> <p>To make sure the front-end proxy is doing what it ought to, you can disable Dancer's built-in handling of static resources by adding this to your <code>config.yml</code> file:</p> <pre class="prettyprint">static_handler: 0</pre> <p>Reload the web app, then work through all of the app's routes to make sure you don't get any new 404 errors. It may be helpful to open the Network tab in your browser's developer tools alongside the browser window you're testing your web app in so that you're more likely to notice any new errors that happen in background Ajax calls.</p> <p>Running a typical web app this way might reduce the number of hits that get down to the Dancer level by a factor of 10 to 100 since so much of a modern web app is composed of static asset files: bitmaps, fonts, CSS files, JavaScript files, etc.</p> <p>You might want to take this a step further, in fact. Instead of merely disabling Dancer's static file handler in your <code>config.yml</code> file for the duration of a single test session, you could instead disable it permanently in your <code>environments/development.yml</code> file to ensure that you find and fix such problems in development, before you deploy to production.</p> <p>I cannot recommend doing this permanently at the <code>config.yml</code> or <code>environments/production.yml</code> levels, because I have occasionally found it useful to be able to put random files into my app's <code>public/</code> directory on production systems so that I can have HTTP access to them via the Dancer app without restarting anything. Case in point: your Dancer app is running on a Linux server at a remote site, and you need to send a file too big to email to someone at that site, but that person runs Windows on their PC, and the Linux box doesn't run Samba, so HTTP is the only easy way they have to get the file from your server onto their PC. (Can you tell that I'm writing from personal experience? Yes, indeed, I am.) Annnnyway, the point is, you don't want to be forced to adjust the front-end proxy settings in such a case to make it handle the <i>ad hoc</i> file transfer. You want the Dancer app to backstop the front-end proxy in such cases, serving up any file the proxy server isn't preconfigured to serve.</p> <p>I can offer a related bit of advice here: if you must change the <code>log_level</code> setting of a Dancer app running in a public-facing production setting, never raise it to <code>core</code>, at least not for very long. Dancer logs all URLs retrieved at that level, and the default Dancer <code>production.yml</code> file is configured to write log messages to a file file, rather than the console. On today's Internet, it is common to encounter bots that do nothing but request nonsense URLs from every web server they can find. These URLs may make sense to certain vulnerable applications, or they may simply be random, as the bot is searching for hidden resources on your server. You don't want a long series of such hits to fill your disk with log messages.</p> <p>Meta-advice: on production systems, configure your OS's log rotation system to keep your Dancer app's log file trimmed to a reasonable size. Dancer doesn't do that on its own. The Dancer2 docs recommend using <code>logrotate</code> in <code>copytruncate</code> mode.</p> <p>In the <a href="http://advent.perldancer.org/2016/7">next part of this article series</a>, we will discover the REST API that was hidden inside this monolithic web app the whole time.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Warren Young for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>&#xa9; 2015, 2016 by Educational Technology Resources, licensed under <a href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0</a></p> </div> Medium-Scale Dancer, Part 3: Views http://advent.perldancer.org/2016/5 perl http://advent.perldancer.org/2016/5 Mon, 5 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="medium_scale_dancer__part_3__views"></a>Medium-Scale Dancer, Part 3: Views</h1> <p>The <a href="http://advent.perldancer.org/2016/3">first</a> two <a href="http://advent.perldancer.org/2016/4">parts</a> of this article series broke the monolithic <code>lib/App.pm</code> file up into a series of Perl modules, each focused on a functional centroid of the application.</p> <p>If we describe the default <code>lib/App.pm</code> file as monolithic, then we might get away with describing the app's <code>views/</code> tree as "polylithic" because there is no monolith to break up; the template files in this subtree naturally map to web pages, so the app's URL scheme effectively keeps them separated by purpose.</p> <p>Although we will not start this part of the series needing to break up an overly large file, I can pass along some tips that might cause you to rethink the current structure of your app's <code>views/*</code> tree.</p> <h2><a name="the_view_naming_scheme_should_match_the_url_scheme"></a>The View Naming Scheme Should Match the URL Scheme</h2> <p>Older web frameworks like PHP, ASP, and JSP define the web app's URL structure in the file system. The route scheme defined in the previous part of this article series would look like this in PHP:</p> <pre class="prettyprint">index.php mf/index.php mf/sf/index.php</pre> <p>The view code &#x2014; HTML and inline JavaScript &#x2014; is intermixed with the server-side code in the same file. Worse, single files like <code>mf/sf/index.php</code> have to handle multiple HTTP verbs; in our example, <code>GET</code>, <code>POST</code>, <code>PUT</code>, and <code>DELETE</code>. If each verb returns a different web page, you end up with a huge top-level <code>if/elseif/else</code> block dividing the file up into a bunch of logically separate chunks. There are other bad consequences to this web framework design choice, such as that if you want your text editor to do syntax coloring correctly, it needs to be able to switch among PHP, JavaScript, and HTML syntax, all within the same file. The programmer ends up needing to do the same sort of context switching, too.</p> <p>Simply put, this is a mess.</p> <p><a href="http://www.template-toolkit.org/">Template::Toolkit</a> &#x2014; Dancer's default template system &#x2014; solves part of this problem by separating the view files from the server-side Perl code. Modern web app development frameworks like <a href="https://angularjs.org/">Angular</a> solve the rest of it by encouraging you to move all of your JavaScript code into separate <code>*.js</code> files, rather than put it inline in the HTML file.</p> <p>There is nothing about the way Dancer works that enforces or even encourages any particular <code>views/*</code> file naming scheme. Thus this tip: for your own sanity, I recommend that you name your template files after the corresponding route. The Dancer scheme corresponding to the above PHP scheme might look something like this:</p> <pre class="prettyprint">views/top.tt views/mf/top.tt views/mf/sf/get.tt views/mf/sf/post.tt views/mf/sf/put.tt views/mf/sf/delete.tt</pre> <p>This scheme maps Dancer routes 1:1 to template files, using a naming scheme that is easy to remember since it's nearly identical to the URL scheme. It's so simple a mapping that you could write a Perl one-liner to do the transform. Restricting yourself to a simple naming convention removes a whole class of details that you have to keep in mind while working on your web app; you don't have to guess where the template file for a given route handler lives, you already <i>know</i> where it lives. You will quickly rediscover this simple mapping years from now when you have to work on the web app again.</p> <p>This naming scheme is very much a suggestion, rather than a prescription. For one thing, you may find that the <code>DELETE /mf/sf</code> route needs no view, because it just deletes one database record and then redirects you to <code>GET /mf/sf</code> to show the change in the normal view. In that case, you would not need <code>views/mf/sf/delete.tt</code>.</p> <p>The important thing is to <i>have</i> a well-thought-out naming scheme, not necessarily to follow the one I've laid out above.</p> <h2><a name="factor_common_ui_elements_out"></a>Factor Common UI Elements Out</h2> <p>If you reuse a particular UI element across different parts of your web app, put its template file into a special subdirectory of <code>views/</code>. I use <code>views/parts</code> for this.</p> <p>If you have an HTML fragment page that is incorporated into your web app dynamically on the client side via Ajax, you will need a corresponding Dancer route for it, and probably a Perl module for it, too:</p> <pre class="prettyprint">views/parts/component.tt lib/App/Parts/Component.pm</pre> <p>Then in <code>lib/App/Parts/Component.pm</code>:</p> <pre class="prettyprint">sub _get { # ...work out how to build the component return template '/parts/component' =&gt; { stuff =&gt; 'goes here' }; } prefix '/parts' =&gt; sub { get 'component' =&gt; \&amp;_get; };</pre> <p>I chose the naming scheme for the function carefully. I want to be able to use short names here that correspond to the HTTP verb that the function handles without colliding with the short names exported by Dancer's DSL. The <a href="http://perldoc.perl.org/perlstyle.html">standard Perl style rules</a> say that a leading underscore marks a function that isn't meant to be called from outside the module, which is exactly correct here; only the route handler defined below that function should be calling it.</p> <p>You may prefer a different scheme, such as <code>Get()</code>, even though this is unconventional Perl style. Again, the important thing is to <i>have</i> a consistent style, not that you use the style I've chosen here.</p> <p>One argument in favor of <code>Get()</code> over <code>_get()</code> is that you might need to be able to reuse this route handler in another of your Perl modules, bodily incorporating the HTML fragment within another web page on the server side, thus saving an Ajax round trip the first time that that web page is served.</p> <p>For example, <code>lib/App/MajorFeature.pm</code> might have something like this in it:</p> <pre class="prettyprint">sub Get { # Work out how to build the main part of the top-level /mf page ...Perl code here... # Assemble the pieces return template '/mf/top' =&gt; { component =&gt; App::Parts::Component::Get(), other_stuff =&gt; 'goes here', }; } prefix '/mf' =&gt; sub { get '/' =&gt; \&amp;Get; # other route handlers here };</pre> <p>Then within <code>views/mf/top.tt</code>, you can reference <code>$component</code> to bodily include that component's HTML fragment into the larger page.</p> <p>Now that we have sorted out the purely server-side HTML and Perl code files, we will look at the Dancer app design decisions that affect its presentation to the browser in the <a href="http://advent.perldancer.org/2016/6">next part of this article series</a>.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Warren Young for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>&#xa9; 2015, 2016 by Educational Technology Resources, licensed under <a href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0</a></p> </div> Medium-Scale Dancer, Part 2: Route Definitions http://advent.perldancer.org/2016/4 perl http://advent.perldancer.org/2016/4 Sun, 4 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="medium_scale_dancer__part_2__route_definitions"></a>Medium-Scale Dancer, Part 2: Route Definitions</h1> <p>By the time a Dancer app grows large enough that you want to start breaking it up into multiple Perl modules, as in the <a href="http://advent.perldancer.org/2016/3">previous article in this series</a>, you've probably also defined enough routes that you're starting to have problems managing them all. Just as with the Perl code, Dancer lets us break up the monolithic route definition set, too.</p> <p>If you structured your app in the way recommended in the previous article, each major feature of your web app is now in its own Perl module. That Perl module's name likely corresponds to some part of your app's URL scheme. Let's say you're exposing the features of <code>App::MajorFeature</code> as <code>/mf</code> in URLs, with sub-features defined in <code>App::MajorFeature::SubFeature</code> and exposed via <code>/mf/sf</code> routes.</p> <p>If you extend the generated <code>lib/App.pm</code> file by following the simplest examples from the Dancer documentation, you might have a mess that looks something like this:</p> <pre class="prettyprint">get '/mf' =&gt; sub { # Lots of Perl code to return the top-level MajorFeature view }; get '/mf/sf' =&gt; sub { # Implementation of a sub-feature of MajorFeature }; post '/mf/sf' =&gt; sub { # Maybe you need a way to add new subfeature objects }; put '/mf/sf' =&gt; sub { # And maybe also a way to edit existing subfeature objects }; del '/mf/sf/:id' =&gt; sub { # And a way to delete them, too };</pre> <p>The first thing to fix here is that almost all of the Perl code implementing each route handler should move to <code>lib/App/*.pm</code>. Ideally, each route handler body should do nothing more than call a function in one of these modules:</p> <pre class="prettyprint">get '/mf' =&gt; \&amp;App::MajorFeature::retrieve; get '/mf/sf' =&gt; \&amp;App::MajorFeature::SubFeature::retreive; post '/mf/sf' =&gt; \&amp;App::MajorFeature::SubFeature::add; put '/mf/sf' =&gt; \&amp;App::MajorFeature::SubFeature::modify; del '/mf/sf/:id' =&gt; \&amp;App::MajorFeature::SubFeature::remove;</pre> <p>Notice that by moving all of the code for each route handler into a function in one of our module files, we can replace the inline anonymous function references with explicit fully qualified function references.</p> <p>There's a fair bit of redundancy in that code, which we'll compress out in two stages.</p> <p>First, Dancer has the awesome <a href="https://metacpan.org/pod/distribution/Dancer2/lib/Dancer2/Manual.pod#prefix"><code>prefix</code></a> feature, which lets us express the URL hierarchy directly in the code, without repeating elements of the URL:</p> <pre class="prettyprint">prefix '/mf' =&gt; sub { get '' =&gt; \&amp;App::MajorFeature::retrieve; prefix '/sf' =&gt; sub { get '' =&gt; \&amp;App::MajorFeature::SubFeature::retreive; post '' =&gt; \&amp;App::MajorFeature::SubFeature::add; put '' =&gt; \&amp;App::MajorFeature::SubFeature::modify; del '/:id' =&gt; \&amp;App::MajorFeature::SubFeature::remove; }; };</pre> <p>As you can see, this makes the overall code narrower, because we're not repeating ourselves as much. This move toward using <code>prefix</code> will help considerably later in this series of articles.</p> <p>A second excellent feature of Dancer lets us shorten those lines of code still further.</p> <p>So far, we've been using explicitly-qualified function names. This is because we want to use short function names within the modules (e.g. <code>retrieve()</code>) without causing namespace collisions by exporting all of the functions. But in fact, there is actually no need to expose the API of your modules outside the module itself. Dancer doesn't care <i>where</i> you define the route handlers, just that they're all defined by the time your caller wants to use them. In the previous part of this article series, we said <code>use App::MajorFeature</code> and such within <code>lib/App.pm</code>, so every one of our app's modules gets executed on startup. This means that any code at global scope within these modules also runs at startup.</p> <p>Therefore, we can move all of the route definitions above from <code>lib/App.pm</code> to the end of the module where we define each route's handler. That is, the tail end of <code>lib/App/MajorFeature.pm</code> says:</p> <pre class="prettyprint">prefix '/mf' =&gt; sub { get '' =&gt; \&amp;retrieve; };</pre> <p>...and the tail end of <code>lib/App/MajorFeature/SubFeature.pm</code> says:</p> <pre class="prettyprint">prefix '/mf' =&gt; sub { prefix '/sf' =&gt; sub { get '' =&gt; \&amp;retreive; post '' =&gt; \&amp;add; put '' =&gt; \&amp;modify; del '/:id' =&gt; \&amp;remove; }; };</pre> <p>The route definitions are much shorter now because they refer to module-local functions defined above the route definitions, so the code references don't need to be fully-qualified.</p> <p>Having done all this, all that's left behind in <code>lib/App.pm</code> is Dancer startup and other initialization code, such as hook definitions, as is appropriate for the app's top-level module.</p> <p>The bulk of the application's code is now collected into a set of tightly-scoped modules. These modules should also be largely decoupled since only Dancer needs to know how to call into them, and you told it how from the module itself, by defining routes. Beautiful.</p> <p>In the <a href="http://advent.perldancer.org/2016/5">next part of this series</a>, we will consider how this application restructuring affects the way we arrange our template files on disk.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Warren Young for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>&#xa9; 2015, 2016 by Educational Technology Resources, licensed under <a href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0</a></p> </div> Medium-Scale Dancer, Part 1: Modules http://advent.perldancer.org/2016/3 perl http://advent.perldancer.org/2016/3 Sat, 3 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="medium_scale_dancer__part_1__modules"></a>Medium-Scale Dancer, Part 1: Modules</h1> <h2><a name="or__how_to_get_beyond_small_scale_in_dancer_application_design"></a>Or: How to Get Beyond Small-Scale in Dancer Application Design</h2> <p>When you generate a Dancer app with <code>dancer2 -a App</code>, you get a very nicely structured and useful starting point. As long as your app remains fairly small, you can work with this structure as-is clear through to completion. In that sense, the generated app is production-ready.</p> <p>The problem comes when you get to thousands of lines of Perl code, dozens of templates, and dozens of routes, stretching the stock app design beyond its natural limits. This series of articles gives you one way to extend beyond this base.</p> <p>I say "one way" because Dancer is a policy-free web application framework. Its designers purposely avoid making whole classes of design decisions for you. That means that Dancer not only doesn&#x2019;t force you to design your app the "right way," by its creators' lights, the framework rarely even gives hints about what the right way might be. Dancer prefers to present itself as a box of tools, which you are free to use as you see fit.</p> <p>The design presented here is working quite well for us, so we think it is worthy of emulation, but we do not expect that it will work for all medium-scale web applications. Think of it as a mutually consistent collection of design ideas, rather than a prescription of the One True Way to design a Dancer application.</p> <h2><a name="the_generated_files"></a>The Generated Files</h2> <p>When you say <code>dancer2 -a App</code> at the command line, you get a few dozen files. Several of these files contain Perl code, but only one of those is interesting for the purposes of this article.</p> <p>We're setting <code>bin/app.psgi</code> and <code>public/dispatch.*</code> aside as "uninteresting" here because we recommend that you leave these files as-is. None of your app-specific Perl code should go in these files.</p> <p>We're also ignoring <code>Makefile.PL</code> since it's part of the app's build system, not part of the app proper.</p> <p>That only leaves <code>lib/App.pm</code>. For small-scale apps, simply piling all of your Dancer-related app code into this file is just fine. Up to about one or two thousand lines of code, you can just use it as-is, for the same reason that a thousand-line monolithic Perl script is fine in other contexts, too.</p> <h2><a name="extending_the_stock_scheme"></a>Extending the Stock Scheme</h2> <p>One of the nicest things about Dancer is that the generated startup code adds the app's <code>lib</code> directory to the Perl module path. That leads to an obvious solution to the problem of too much code in a single file: break it out into other <code>*.pm</code> files in the <code>lib</code> directory. But how, exactly?</p> <p>I recommend following the example of CPAN, with a structure like the following:</p> <pre class="prettyprint">lib/App.pm # your app's main module lib/App/MajorFeature.pm # implementation of a major app feature lib/App/OtherFeature.pm # as many feature impl files as you need lib/App/API.pm # if your app has a REST API, put it here lib/App/Const.pm # maybe you have some app-wide constants lib/App/Utility.pm # every big app has a "junk drawer" module</pre> <p>Then in <code>lib/App.pm</code>, you <code>use</code> all of these modules:</p> <pre class="prettyprint">use App::MajorFeature; use App::OtherFeature; use App::API; use App::Const; use App::Utility;</pre> <p>How you design these modules is up to you. The <a href="http://stackoverflow.com/questions/410359/how-can-i-learn-to-write-well-structured-programs-in-perl">standard rules</a> for well-structured Perl application design apply.</p> <p>There is one Dancer2-specific thing to beware of here, though: you must <a href="http://advent.perldancer.org/2014/10">set the <code>appname</code> property on the sub-modules</a>. If you don't, each sub-module will be considered a separate Dancer2 application, which puts unwanted barriers between the modules.</p> <p>(Dancer1 didn't have this requirement because it didn't have any concept of multiple apps within a single Dancer instance.)</p> <p>When it comes time to break <code>lib/App.pm</code> up into multiple modules, I recommend that you move almost all Perl code into one of these modules, leaving only application initialization code in the top-level module.</p> <p>(This, by the way, is why we don't need to modify <code>bin/app.psgi</code>: since it pretty much just loads Dancer and then calls <code>lib/App.pm</code>, there is no point in splitting app initialization code across the two files. Let <code>bin/app.psgi</code> remain a tiny little glue file that exists merely to make <a href="http://plackperl.org/">PSGI</a> happy.)</p> <p>Your initial refactoring of <code>lib/App.pm</code> will likely leave all the route definitions behind, which is fine because refactoring the routes is the subject of the next article in this series.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Warren Young for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>&#xa9; 2015, 2016 by Educational Technology Resources, licensed under <a href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0</a></p> </div> State of the Ecosystem http://advent.perldancer.org/2016/2 perl http://advent.perldancer.org/2016/2 Fri, 2 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="state_of_the_ecosystem"></a>State of the Ecosystem</h1> <p>At least 15 new plugins saw their first CPAN release in 2016 bringing the total number of <a href="https://metacpan.org/module/Dancer2">Dancer2</a> plugins beyond the 70 mark.</p> <p>2016 also saw many plugins converted to the new <code>Plugin2</code> architecture. When using the new <a href="https://metacpan.org/module/Dancer2::Plugin">Dancer2::Plugin</a> plugins can now use other plugins and have their DSL directly available. At the last count 20 plugins have been released that use <code>Plugin2</code> but there is still work to do. If you want to help out checkout the related <a href="https://github.com/PerlDancer/Dancer2/issues/1078">GitHub issue</a>.</p> <p>Thankyou to everyone for contributing your code, and your time, to help make the Dancer2 ecosystem even better.</p> <h2><a name="new_plugins_in_2016"></a>New Plugins in 2016</h2> <h3><a name="auth__activedirectory"></a>Auth::ActiveDirectory</h3> <p>Mario Zieschang gave us <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::ActiveDirectory">Dancer2::Plugin::Auth::ActiveDirectory</a> in April. Thanks Mario!</p> <p>I haven't played with this one myself as I don't have any Windows servers but it could be a good option for AD environments. See also <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Extensible::Provider::LDAP">Dancer2::Plugin::Auth::Extensible::Provider::LDAP</a>.</p> <h3><a name="auth__extensible__provider__imap"></a>Auth::Extensible::Provider::IMAP</h3> <p>In October Jason Lewis asked about an IMAP provider for <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Extensible">Dancer2::Plugin::Auth::Extensible</a> on the <a href="https://chat.mibbit.com/?channel=%23dancer&amp;server=irc.perl.org">#dancer IRC channel</a>. I like a challenge so decided to create one that afternoon. The result was released as: <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Extensible::Provider::IMAP">Dancer2::Plugin::Auth::Extensible::Provider::IMAP</a>.</p> <h3><a name="auth__extensible__provider__ldap"></a>Auth::Extensible::Provider::LDAP</h3> <p>Although this existed in a git repo, it had no tests, was AD-specific and was not released to CPAN. In October I released a shiny new <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Extensible::Provider::LDAP">Dancer2::Plugin::Auth::Extensible::Provider::LDAP</a> which tries to be a little more LDAP server agnostic (and also has a good number of tests). Thanks to J. Stebens (corecache) for feedback and testing it against OpenLDAP.</p> <h3><a name="auth__safe"></a>Auth::SAFE</h3> <p>Released whilst this article was being written on 29th November by &#x41a;&#x43e;&#x43d;&#x441;&#x442;&#x430;&#x43d;&#x442;&#x438;&#x43d; &#x41c;&#x430;&#x442;&#x44e;&#x445;&#x438;&#x43d; (KVENTIN), <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::SAFE">Dancer2::Plugin::Auth::SAFE</a> brings authentication via Thomson Reuters SAFE SSO to your Dancer app.</p> <h3><a name="beforeroute"></a>BeforeRoute</h3> <p>Michael CH Vu released his first <a href="https://metacpan.org/module/Dancer2">Dancer2</a> version of his plugin <a href="https://metacpan.org/module/Dancer2::Plugin::BeforeRoute">Dancer2::Plugin::BeforeRoute</a> in August. This plugin allows you to add <code>before</code> hooks to specific routes.</p> <h3><a name="cart"></a>Cart</h3> <p>Need a simple and flexible cart in your <a href="https://metacpan.org/module/Dancer2">Dancer2</a> app? Need something that can work with a new or existing database? Maybe the new Cart plugin is for you.</p> <p>Andrew Baerg and Ruben Amortegui made the first release of <a href="https://metacpan.org/module/Dancer2::Plugin::Cart">Dancer2::Plugin::Cart</a> in July, and Andrew went on to give a talk about it at the <a href="https://perl.dance">Perl Dancer Conference</a> in Vienna in September. You can find a demo app that Andrew created for his talk <a href="https://github.com/pullingshots/Cart-Demo">on GitHub</a>.</p> <h3><a name="debugger"></a>Debugger</h3> <p>More than just a plugin, <a href="https://metacpan.org/module/Dancer2::Debugger">Dancer2::Debugger</a> brings Stevan Little's <a href="https://metacpan.org/module/Plack::Debugger">Plack::Debugger</a> to the <a href="https://metacpan.org/module/Dancer2">Dancer2</a> ecosystem with extra Dancer-specific panels.</p> <p>If you've ever used Marcel Grunauer's excellent <a href="https://metacpan.org/module/Plack::Middleware::Debug">Plack::Middleware::Debug</a> with your Dancer1 apps then this is what you'll want to use with <a href="https://metacpan.org/module/Dancer2">Dancer2</a>.</p> <p>I'm not completely happy with the internals of this thing but I needed it in a hurry and hopefully I'll find time soon for a cleanup. Released in April, you can find my conference talk <a href="https://www.perl.dance/talks/41-plack-debugger-meets-dancer2">here</a>.</p> <h3><a name="encryptid"></a>EncryptID</h3> <p>Rakesh Kumar Shardiwal's <a href="https://metacpan.org/module/Dancer2::Plugin::EncryptID">Dancer2::Plugin::EncryptID</a>, released in July, makes it easy to obfuscate internal IDs when using them in a URL given to users. Instead of seeing <code>http://example.com/item/42</code> users will instead see <code>http://example.com/item/c98ea08a8e8ad715</code>. This prevents nosy users from trying to iterate all items based on a simple ID in the URL.</p> <h3><a name="http__auth__extensible"></a>HTTP::Auth::Extensible</h3> <p>Theo van Hoesel released <a href="https://metacpan.org/module/Dancer2::Plugin::HTTP::Auth::Extensible">Dancer2::Plugin::HTTP::Auth::Extensible</a> in January. This plugin is a fork of <a href="https://metacpan.org/module/Dancer2::Plugin::Auth::Extensible">Dancer2::Plugin::Auth::Extensible</a> but with authentication via WWW-Authenticate header instead of using form + session.</p> <h3><a name="interchange6"></a>Interchange6</h3> <p>Part of the <a href="https://metacpan.org/module/Interchange6">Interchange6</a> e-commerce project, <a href="https://metacpan.org/module/Dancer2::Plugin::Interchange6">Dancer2::Plugin::Interchange6</a> was released in May. <a href="https://metacpan.org/module/Interchange6">Interchange6</a> is a project founded by long-time <a href="http://www.icdevgroup.org">Interchange</a> developer Stefan Hornburg (Racke).</p> <p>The Interchange6 project has so far released the following components:</p> <ul> <li><a name="item__a_href__https___metacpan_org_module_Interchange6__Schema__Interchange6__Schema__a_"></a><b><a href="https://metacpan.org/module/Interchange6::Schema">Interchange6::Schema</a></b> <p>A schema using <a href="https://metacpan.org/module/DBIx::Class">DBIx::Class</a> along with business logic.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_Interchange6__Interchange6__a_"></a><b><a href="https://metacpan.org/module/Interchange6">Interchange6</a></b> <p>A cart built using <a href="https://metacpan.org/module/Moo">Moo</a>.</p> </li> <li><a name="item__a_href__https___metacpan_org_module_Dancer2__Plugin__Interchange6__Dancer2__Plugin__Interchange6__a_"></a><b><a href="https://metacpan.org/module/Dancer2::Plugin::Interchange6">Dancer2::Plugin::Interchange6</a></b> <p>Links the schema with the cart and provides keywords for use in your webshop.</p> </li> </ul> <p>We're still working on a demo shop, due out Christmas. ;-)</p> <h3><a name="minify"></a>Minify</h3> <p><a href="https://metacpan.org/module/Dancer2::Plugin::Minify">Dancer2::Plugin::Minify</a> is a wrapper for HTML::Packer, JavaScript::Packer and CSS::Packer. Released in April, thanks David Zurborg!</p> <h3><a name="pagehistory"></a>PageHistory</h3> <p>A port of my old Dancer1 plugin, <a href="https://metacpan.org/module/Dancer2::Plugin::PageHistory">Dancer2::Plugin::PageHistory</a> was released in June. The <code>add_to_history</code> keyword which is exported by this plugin allows you to add interesting items to the session-based history lists which are returned using the <a href="https://metacpan.org/module/history">history</a> keyword.</p> <h3><a name="pg"></a>Pg</h3> <p>Back in April, Lucas Tiago de Moraes released <a href="https://metacpan.org/module/Dancer2::Plugin::Pg">Dancer2::Plugin::Pg</a>, another twist on relational database plugins.</p> <p>See also: <a href="https://metacpan.org/module/Dancer2::Plugin::Database">Dancer2::Plugin::Database</a> and <a href="https://metacpan.org/module/Dancer2::Plugin::DBIC">Dancer2::Plugin::DBIC</a>.</p> <h3><a name="swagger2"></a>Swagger2</h3> <p>Something I'd like to play with, <a href="https://metacpan.org/module/Dancer2::Plugin::Swagger2">Dancer2::Plugin::Swagger2</a> was released by Daniel B&#xf6;hmer in March. This plugin creates routes directly from a Swagger (AKA OpenAPI) file. Neat.</p> <h3><a name="tail"></a>Tail</h3> <p>Released in August, Jack Bilemjian's <a href="https://metacpan.org/module/Dancer2::Plugin::Tail">Dancer2::Plugin::Tail</a> allows you to tail a file from within your <a href="https://metacpan.org/module/Dancer2">Dancer2</a> application.</p> <h3><a name="templateflute"></a>TemplateFlute</h3> <p><a href="https://metacpan.org/module/Dancer2::Plugin::TemplateFlute">Dancer2::Plugin::TemplateFlute</a>, along with its sister distro <a href="https://metacpan.org/module/Dancer2::Template::TemplateFlute">Dancer2::Template::TemplateFlute</a>, brings Racke's <a href="https://metacpan.org/module/Template::Flute">Template::Flute</a> forms to <a href="https://metacpan.org/module/Dancer2">Dancer2</a>. Released in May 2016, we needed this in order to port the <a href="https://perl.dance">Perl Dancer Conference</a> website code from Dancer1.</p> <h2><a name="author"></a>Author</h2> <p>This article has been written by Peter Mottram for the Perl Dancer Advent Calendar 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>2016 // Peter Mottram (SysPete) <code>&lt;peter@sysnix.com&gt;</code></p> </div> Another year of dancing http://advent.perldancer.org/2016/1 perl http://advent.perldancer.org/2016/1 Thu, 1 Dec 2016 00:00:00 -0000 <div class="pod-document"><h1><a name="another_year_of_dancing"></a>Another year of dancing</h1> <p>It's been a while since we had an advent calendar. It's about time.</p> <p>You might be wondering what we've been up to in the last year. Well, a lot.</p> <ul> <li><a name="item_New_members"></a><b>New members</b> <p>Please welcome two new core team members:</p> <ul> <li><a name="item_Peter___SysPete__Mottram"></a><b>Peter (@SysPete) Mottram</b> <p>If you have raised an issue, you have likely interacted with Peter. He takes care of the queue, co-organizes the conferences, and managed the entire transition to the new plugin architecture, helping authors by testing their code and transitioning the syntax.</p> <p>Oh, new plugin architecture? More to follow.</p> </li> <li><a name="item_Jason___CromeDome__Crome"></a><b>Jason (@CromeDome) Crome</b> <p>Jason Crome started by fixing up the documentation and moved on to help with the releases themselves. If you looked up Dancer2 recently on CPAN, you probably recognize his picture by now. :)</p> <p>Jason's handling of the releases allows us to maintain a higher quality of releases, including timing, announcements, and double checking the important Pull Requests and issues are resolved prior to the release.</p> </li> </ul> </li> <li><a name="item_New_features"></a><b>New features</b> <ul> <li><a name="item_Asynchronous_streaming_responses"></a><b>Asynchronous streaming responses</b> <p>We have finally introduced the ability to provide asynchronous and streaming responses. This allows you to do various interesting things, but it can be quite complex.</p> <p>This topic has its own article in this year's advent calendar. Stay tuned!</p> </li> <li><a name="item__code_prefix__code__supports_the_route_spec"></a><b><code>prefix</code> supports the route spec</b> <p>The <code>prefix</code> syntax allowed you to reduce the repeated parts of strings, and it now supports the full spec in order to allow you to reduce the pattern strings:</p> <pre class="prettyprint">prefix '/:action' =&gt; sub { get '/:entity' =&gt; sub {...}; };</pre> </li> <li><a name="item__code_send_file__code__is_now_streaming"></a><b><code>send_file</code> is now streaming</b> <p>The <code>send_file</code> keyword will now also stream the response asynchronously if it's available. You don't need to think about it. You don't even know it does it, but it does, automatically, or you. :)</p> </li> <li><a name="item_New_keywords"></a><b>New keywords</b> <ul> <li><a name="item_New_parameters_keywords"></a><b>New parameters keywords</b> <p>We have introduced new keywords to retrieve information from the route, query, or body parameters. They help handle common incorrect and risky patterns.</p> <p>They will also appear in their own advent article. Stay tuned!</p> </li> <li><a name="item_New_header_keywords"></a><b>New header keywords</b> <p>Noticing we only have headers to handle the response headers, we have introduced several keywords to help you handle the request headers.</p> <ul> <li><a name="item__code_request_header__code__"></a><b><code>request_header</code>.</b> <p>Return the request header.</p> </li> <li><a name="item__code_response_header__code__"></a><b><code>response_header</code>.</b> <p>A more explicit alternative to <code>header</code>.</p> </li> <li><a name="item__code_response_headers__code__"></a><b><code>response_headers</code>.</b> <p>A more explicit alternative to <code>headers</code>.</p> </li> <li><a name="item__code_push_response_header__code__"></a><b><code>push_response_header</code>.</b> <p>A more explicit alternative to <code>push_header</code>.</p> </li> </ul> <p>You will notice you cannot <i>push</i> a request header. This is on purpose, since request headers should not change, they only represent the request you received.</p> <p>(We might eventually deprecate the general <code>header</code> and <code>push_header</code> keywords.)</p> </li> <li><a name="item__code_send_as__code_"></a><b><code>send_as</code></b> <p>The <code>send_as</code> keyword gets around the serializer.</p> <p>Interested? It has its own advent article!</p> </li> <li><a name="item_Local_config_files"></a><b>Local config files</b> <p>You can now provide additional local configuration files that will be loaded, but can be kept out of a version control repository.</p> <p>Stay tuned for an article on that!</p> </li> <li><a name="item_New_config_option__code_change_session_id__code_"></a><b>New config option <code>change_session_id</code></b> <p>We have added a configuration option for improved security in cookies. We will feature an article on them as well.</p> </li> <li><a name="item_New_keywords__code_encode_json__code____code_decode_json__code_"></a><b>New keywords <code>encode_json</code>, <code>decode_json</code></b> </li> </ul> </li> <li><a name="item__code_template__code__keyword_global"></a><b><code>template</code> keyword global</b> <p>The <code>template</code> keyword can now be used outside a request. The relevant request-specific variables will not be available (since it's outside a request), but everything else will be available.</p> </li> <li><a name="item__code_eval__code__shim"></a><b><code>eval</code> shim</b> <p>You now have a shim for <code>eval</code> behavior. If you need such an option, you already understand what it means.</p> </li> <li><a name="item_Support_304_Not_Modified"></a><b>Support 304 Not Modified</b> <p>We properly support <b>304 Not Modified</b> when serving static files.</p> </li> </ul> </li> <li><a name="item_New_documentation"></a><b>New documentation</b> <p>We have revamped our documentation.</p> <p>The original documentation had irrelevant parts from Dancer 1 which no longer apply to Dancer 2, outdated components, unclear and confusing descriptions, and quite honestly, were hard to navigate.</p> <p>The rewritten documentation focus on clarifying how a Dancer 2 program is constructed, the definitions we use and what they mean, the important keywords, and how to use the syntax.</p> <p>It does not delve into deprecated patterns, nor does it explain it. The reasoning is that you could find it if you search, but we don't want to teach you what you shouldn't be doing.</p> <p>Documentation is a live project at any given time and our documentation is no different. This means we always need additional help with it. If you find something to improve, please let us know. We would appreciate your help.</p> </li> <li><a name="item_Memory_leaks_sealed"></a><b>Memory leaks sealed</b> <p>We have become better at identifying memory leaks and resolved a few important ones. We've also added various tests to improve our detection, which so far yield no additional ones.</p> </li> <li><a name="item_Speedups"></a><b>Speedups</b> <p>Prompted by a user mentioning they still use Dancer 1 because it is faster, we have pushed hard and sped up Dancer 2 by quite a bit. It now does not match Dancer 1, but surpasses it.</p> <p>Here are some of the specific work we did:</p> <ul> <li><a name="item_Optimized_routing"></a><b>Optimized routing</b> <p>The routing itself has been optimized. We have a few more plans for this part, but it is now faster and better.</p> </li> <li><a name="item_Fewer_layers__fewer_dependencies"></a><b>Fewer layers, fewer dependencies</b> <p>We removed various layers (such as Middlewares) and removed some dependencies in order to get more direct access to faster components.</p> <p>We're learning where we can push more against abstractions and when we need to use them despite possible slower performance.</p> </li> <li><a name="item_Better_request_object"></a><b>Better request object</b> <p>Our request object has been rewritten. It was originally our own custom object, written from scratch, but now it subclasses the useful <a href="https://metacpan.org/module/Plack::Request">Plack::Request</a> while adding Dancer-specific bits or components that were rejected from being included in the basic Plack class.</p> </li> <li><a name="item_Faster_headers"></a><b>Faster headers</b> <p>We now internally use a faster header library, which is also used by Plack itself: <a href="https://metacpan.org/module/HTTP::Headers::Fast">HTTP::Headers::Fast</a>. We recommend using <a href="https://metacpan.org/module/HTTP::XSHeaders">HTTP::XSHeaders</a> which we co-authored, which will speed your headers substantially.</p> </li> <li><a name="item_Faster_cookies"></a><b>Faster cookies</b> <p>We will optionally use <a href="https://metacpan.org/module/HTTP::XSCookies">HTTP::XSCookies</a> if it's available in order to speed up the cookie handling.</p> </li> <li><a name="item_Faster_serializers_and_config_loader"></a><b>Faster serializers and config loader</b> <p>The JSON serializer will use <a href="https://metacpan.org/module/JSON::MaybeXS">JSON::MaybeXS</a> which will optionally use an XS implementation of <a href="https://metacpan.org/module/JSON">JSON</a>, if available.</p> </li> </ul> </li> <li><a name="item_DancerConf_2015_and_DancerConf_2016"></a><b>DancerConf 2015 and DancerConf 2016</b> <p>We have held two conferences over the last two years.</p> <p>While we're still working on the videos for DancerConf 2016, you can already find the videos for DancerConf 2015 on <a href="https://www.youtube.com/watch?v=UbU5R-SHbDE&amp;list=PLf1KDvMbyeCQq4mkMt8jDPzS9uPUX_mNo">YouTube!</a>.</p> </li> <li><a name="item_New_plugin_architecture"></a><b>New plugin architecture</b> <p>The plugin architecture in Dancer 2 was one of the big remaining weak points. We had to resolve it.</p> <p>It had now been completely rewritten, and it has its own advent article in this calendar!</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 2016.</p> <h2><a name="copyright"></a>Copyright</h2> <p>No copyright retained. Enjoy.</p> <p>Sawyer X.</p> </div>