Acme-CPANModulesBundle-Import-MojoliciousAdvent-2017

 view release on metacpan or  search on metacpan

LICENSE  view on Meta::CPAN

 Copyright (C) 1989 Free Software Foundation, Inc.
 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The license agreements of most software companies try to keep users
at the mercy of those companies.  By contrast, our General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  The
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of a such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the

LICENSE  view on Meta::CPAN

General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program.  You may charge a fee for the physical act of
transferring a copy.

  2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:

    a) cause the modified files to carry prominent notices stating that
    you changed the files and the date of any change; and

    b) cause the whole of any work that you distribute or publish, that
    in whole or in part contains the Program or any part thereof, either
    with or without modifications, to be licensed at no charge to all
    third parties under the terms of this General Public License (except
    that you may choose to grant warranty protection to some or all
    third parties, at your option).

    c) If the modified program normally reads commands interactively when
    run, you must cause it, when started running for such interactive use
    in the simplest and most usual way, to print or display an
    announcement including an appropriate copyright notice and a notice
    that there is no warranty (or else, saying that you provide a
    warranty) and that users may redistribute the program under these
    conditions, and telling the user how to view a copy of this General
    Public License.

    d) You may charge a fee for the physical act of transferring a
    copy, and you may at your option offer warranty protection in
    exchange for a fee.

Mere aggregation of another independent work with the Program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.

  3. You may copy and distribute the Program (or a portion or derivative of
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:

    a) accompany it with the complete corresponding machine-readable

LICENSE  view on Meta::CPAN

YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS

        Appendix: How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to humanity, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.

  To do so, attach the following notices to the program.  It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) 19yy  <name of author>

LICENSE  view on Meta::CPAN


1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
duplicate all of the original copyright notices and associated disclaimers.

2. You may apply bug fixes, portability fixes and other modifications derived
from the Public Domain or from the Copyright Holder. A Package modified in such
a way shall still be considered the Standard Version.

3. You may otherwise modify your copy of this Package in any way, provided that
you insert a prominent notice in each changed file stating how and when you
changed that file, and provided that you do at least ONE of the following:

  a) place your modifications in the Public Domain or otherwise make them
     Freely Available, such as by posting said modifications to Usenet or an
     equivalent medium, or placing the modifications on a major archive site
     such as ftp.uu.net, or by allowing the Copyright Holder to include your
     modifications in the Standard Version of the Package.

  b) use the modified Package only within your corporation or organization.

  c) rename any non-standard executables so the names do not conflict with

devdata/https_mojolicious.io_blog_2017_12_01_day-1-getting-started  view on Meta::CPAN


<h2>Running Your Application</h2>

<p>Mojolicious applications (as we&#39;ll see in another post) are more than just web servers.
In order to use them as one, we need to start it as a web server.</p>

<p>Mojolicious comes with four built-in servers</p>

<ul>
<li><code>daemon</code>, single-threaded, the basis of all the others</li>
<li><code>morbo</code>, the development server, restarts on files changes</li>
<li><code>prefork</code>, optimized production server</li>
<li><code>hypnotoad</code>, like prefork but with hot-restart capability</li>
</ul>

<p><code>daemon</code> and <code>prefork</code> are application commands and are run like</p>

<pre><code>perl hello.pl daemon
</code></pre>

<p>These will work, but for development let&#39;s use <code>morbo</code>.

devdata/https_mojolicious.io_blog_2017_12_02_day-2-the-stash  view on Meta::CPAN

};
app-&gt;start;
</code></pre>

<h2>Stash Defaults</h2>

<p>In the above example we saw how you can set a stash value during a request to control the response.
Remember that the action callback is only called when a request comes in.
However, there is nothing special about the requst that we need to wait for to understand how to respond to it.</p>

<p>In Mojolicious, when establishing a route, we can also specify some default values to add to the stash on each request (unless they are changed).
These defaults are passed as a hash reference to the route constructor <code>get</code>.</p>

<pre><code>use Mojolicious::Lite;
get &#39;/&#39; =&gt; {text =&gt; &#39;Hello 🌍 World!&#39;} =&gt; sub {
  my $c = shift;
};
app-&gt;start;
</code></pre>

<p>However now our action doesn&#39;t do anything, so we don&#39;t actually need it at all, and we are back to our original example.</p>

devdata/https_mojolicious.io_blog_2017_12_03_day-3-using-named-routes  view on Meta::CPAN

  Say hi to &lt;%= link_to &#39;Santa&#39; =&gt; staff =&gt; {name =&gt; &#39;santa&#39;} %&gt;
  and &lt;%= link_to &#39;Rudolph&#39; =&gt; staff =&gt; {name =&gt; &#39;rudolph&#39;} %&gt;.
&lt;/p&gt;

&lt;p&gt;
  And just wait until you see our amazing
  &lt;%= link_to &#39;new puzzle&#39; =&gt; toy =&gt; {toy_name =&gt; &#39;puzzle&#39;} %&gt;!
&lt;/p&gt;
</code></pre>

<p>Because the staff page urls were generated by name, Santa didn&#39;t need to change anything but the route definition!</p>

<h2>Route Names as Default Template Names</h2>

<p>There is one more thing I should mention.
I could have actually made the previous examples with even less code.
If a route doesn&#39;t explicitly render something, it will check to see if a template exists for the name of the route.
It is a shortcut that some people like and could have made the routing definitions look like this:</p>

<pre><code>get &#39;/toy/:toy_name&#39; =&gt; &#39;toy&#39;;
get &#39;/meet/:name&#39; =&gt; &#39;staff&#39;;

devdata/https_mojolicious.io_blog_2017_12_06_day-6-adding-your-own-commands  view on Meta::CPAN

As we saw before, several are available built-in to the system.
However others are available from CPAN, for example, I have a <a href="https://metacpan.org/pod/Mojolicious::Command::nopaste">nopaste clone</a> that when installed is available via your application or the <code>mojo</code> executable.</p>

<p>Your application can add to or even replace the default namespace search path by setting <a href="http://mojolicious.org/perldoc/Mojolicious#commands"><code>app-&gt;commands-&gt;namespaces</code></a>.
My <a href="https://metacpan.org/pod/Galileo">Galileo</a> CMS adds a command namespace so that its deploy command is available as <code>galileo deploy</code> but not as <code>mojo deploy</code>.
Meanwhile plugins that your app loads can add to the namespaces.
The <a href="http://mojolicious.org/perldoc/Minion">Minion</a> job queue is added to your application as a plugin, it appends <code>Minion::command</code> to your command namespaces so that your application has access to the minion commands like star...

<h2>Let&#39;s Build a Weather App</h2>

<p>Rather than give several small examples I&#39;m going to change it up this time and give one big example.
It will be ok if you don&#39;t understand every line, I&#39;m skipping a few pedagogical steps to make this example.</p>

<p>Why don&#39;t we build a weather caching app?
I&#39;ve put the entire thing on github at <a href="https://github.com/jberger/MyWeatherApp">https://github.com/jberger/MyWeatherApp</a>.
I&#39;m going to copy portions of the code into this article for clarity, but consider that that site is probably the most up to date.</p>

<p>Of course, we&#39;ll need some data.
I&#39;ve chosen to use <a href="https://openweathermap.org/">https://openweathermap.org/</a>
To do run this you&#39;ll need to sign up for a <a href="http://home.openweathermap.org/users/sign_up">free account</a>.
It only needs an email address, I tried but I really couldn&#39;t find a totally open access weather API.

devdata/https_mojolicious.io_blog_2017_12_06_day-6-adding-your-own-commands  view on Meta::CPAN

In this case we use one to build and return an instance of our model class.
It attaches that required data that we noted earlier.</p>

<p>Moving on, the application now defines a route.
As we&#39;ll see later it is attached to the <a href="https://github.com/jberger/MyWeatherApp/blob/master/lib/MyWeatherApp/Controller/Weather.pm">Weather controller class</a> and more specifically its <code>recall</code> action method.
This is much like the action callbacks we saw before, but by keeping it in a separate class the application class is easier to read.</p>

<p>Finally we define the database schema.
This is a format common to the Mojo-flavored database modules, like <a href="http://mojolicious.org/perldoc/Mojo/Pg">Mojo::Pg</a>, <a href="https://metacpan.org/pod/Mojo::mysql">Mojo::mysql</a>, and <a href="https://metacpan.org/pod/Mojo::SQLite">Moj...
Each section is defined with a version number and the word <code>up</code> or <code>down</code>.
When migrating versions, it will apply each change set from the current version (beginning at 0) until the version you request.
If you don&#39;t request a version it gets the highest version.</p>

<p>Now that all that is done, we can try it out!</p>

<pre><code>$ perl bin/myweatherapp eval -V &#39;app-&gt;weather-&gt;fetch(&quot;Chicago&quot;)&#39;
</code></pre>

<p>If you&#39;ve configured your appid correctly you should get a dump of weather data about my home city.</p>

<h3>The Commands</h3>

<p>Well finally we have arrived at the whole reason we started this endeavour: the commands!</p>

<p>This example has two different uses for commands.
The first use is to deploy our database schema or to upgrade it should it change.
This would likely be run by an operations manager or configuration management software when installing or upgrading.
The command exists in <a href="https://github.com/jberger/MyWeatherApp/blob/master/lib/MyWeatherApp/Command/deploy.pm">lib/MyWeatherApp/Command/deploy.pm</a>.</p>

<pre><code>package MyWeatherApp::Command::deploy;
use Mojo::Base &#39;Mojolicious::Command&#39;;

use Mojo::Util &#39;getopt&#39;;

has &#39;description&#39; =&gt; &#39;Deploy or update the MyWeatherApp schema&#39;;
has &#39;usage&#39; =&gt; &lt;&lt;&quot;USAGE&quot;;

devdata/https_mojolicious.io_blog_2017_12_10_day-10-give-the-customer-what-they-want  view on Meta::CPAN

<h3>How It Works</h3>

<p>By now you probably suspect, correctly, that the <code>format</code> stash value is the driver of Content Negotiation.
Other methods, which you will see later, will check that value in order to determine what should be rendered.</p>

<p>With that knowledge therefore this way you might guess, correctly, that if you&#39;d like to force a route to have a certain default format you can just put it into the route default stash values</p>

<pre><code>get &#39;/:name&#39; =&gt; {format =&gt; &#39;json&#39;} ...
</code></pre>

<p>In Mojolicious the overall <a href="http://mojolicious.org/perldoc/Mojolicious/Renderer#default_format">default format</a> is html, but of course can be changed.</p>

<pre><code>app-&gt;renderer-&gt;default_format(&#39;json&#39;);
</code></pre>

<p>There are also mechanisms to limit the format detection, but those are beyond the scope of this article.
The links above contain more.</p>

<p>Note also that the mappings between file extensions and MIME types obviously are in play here.
If you have special format types you can add them to the <a href="http://mojolicious.org/perldoc/Mojolicious#types">types</a> object on the application.</p>

devdata/https_mojolicious.io_blog_2017_12_12_day-12-more-than-a-base-class  view on Meta::CPAN

<pre><code>use Mojo::Base -strict;
</code></pre>

<p>and you get everything listed above.
Otherwise, if you use the class or roles functionality then these imports come along for free.</p>

<h3>Experimental Signatures</h3>

<p>In the past few years, Perl has added <a href="https://metacpan.org/pod/perlsub#Signatures">signatures</a> to subroutines as an <a href="https://metacpan.org/pod/perlexperiment">experimental</a> feature.
With Mojolicious&#39; emphasis on non-blocking functionality, and the frequent use of callbacks that that entails, the Mojo community has been especially anxious to use them.
However since these are still experimental, and are still subject to change, when Mojo::Base recently added this functionality, it was decided that it should be an additional opt-in flag.
Using it, suddenly</p>

<pre><code>use Mojo::Base -strict;
$ua-&gt;get(&#39;/url&#39; =&gt; sub {
  my ($ua, $tx) = @_;
  ...
});
</code></pre>

<p>becomes</p>

devdata/https_mojolicious.io_blog_2017_12_12_day-12-more-than-a-base-class  view on Meta::CPAN

<h3>Accessor Methods</h3>

<p>A read/write accessor method is installed into the class for each declared attribute.
However, have one major difference from other common Perl object systems.
While the getters return the value as expected,</p>

<pre><code>my $foo = $self-&gt;foo;
my $value = $self-&gt;data-&gt;{key};
</code></pre>

<p>the setters (ie, when passing an argument to change the stored value) return the object itself, not the value.
The reason for this is to create what is called a <a href="https://en.wikipedia.org/wiki/Fluent_interface">fluent interface</a>, more commonly known as chaining.</p>

<pre><code>my $ua = Mojo::UserAgent-&gt;new-&gt;max_redirects(10)-&gt;inactivity_timeout(1200);
</code></pre>

<p>Many of the Mojo modules support a fluent interface with their methods, so this this nicely consistent.</p>

<pre><code>my $title = Mojo::UserAgent-&gt;new
  -&gt;max_redirects(10)
  -&gt;get(&#39;http://mojolicious.org&#39;)

devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles  view on Meta::CPAN


              <div class="post-thumb">
                <!-- theme suggests 1300x500 -->
                <img alt="Pile of hats" src="/blog/2017/12/13/day-13-more-about-roles/amsterdam_hats.jpg">
              </div>

            <div class="post-content">

              <section id="section-1">
                  <p>Before we get ahead of ourselves, what are roles?
Briefly stated, roles enable composing functionality (usually methods) into a class without without implying a change of inheritence.
Said another way, roles let you specify what a class does without changing what it is.
For a better description, check out Toby Inkster&#39;s article <a href="http://radar.oreilly.com/2014/01/horizontal-reuse-an-alternative-to-inheritance.html">Horizontal Reuse: An Alternative to Inheritance</a>.</p>

<p>An important utility of roles is that you can easily use more than one role at the same time in the same consuming class.
With inheritance, especially of third-party functionality, you have to choose one set of extensions to utilize.
This is because the author of the subclass establishes the inheritance.
In roles, the user determines which roles to compose into the base class.</p>

<p><a href="/blog/2017/12/12/day-12-more-than-a-base-class">Yesterday</a> I ended the discussion of <a href="http://mojolicious.org/perldoc/Mojo/Base">Mojo::Base</a> before discussing the roles support.
Added in several installments between Mojolicious versions <a href="https://metacpan.org/release/SRI/Mojolicious-7.40">7.40</a> and <a href="https://metacpan.org/release/SRI/Mojolicious-7.55">7.55</a>, this role support is one of the most recently ad...

devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles  view on Meta::CPAN

}
</code></pre>

<p>This example shows three interesting features.
First is that even though it is not a class, the package still gets Mojo::Base&#39;s <a href="http://mojolicious.org/perldoc/Mojo/Base#has">has</a> keyword, used to make accessors for attributes.
Second is that a new keyword, <code>requires</code>, has been added, coming from <a href="https://metacpan.org/pod/Role::Tiny#requires">Role::Tiny</a>.
This keyword tells the role that it can only be composed into a class that provides a <code>find</code> method.
Consider the new <code>find_custom</code> method, since it uses <code>find</code> if the class it is composed into didn&#39;t provide that method our new method couldn&#39;t behave as expected.</p>

<p>Indeed several keywords are imported from Role::Tiny including <code>with</code> to compose other roles and several method modifiers coming from <a href="https://metacpan.org/pod/Class::Method::Modifiers">Class::Method::Modifiers</a> (which is an ...
While I won&#39;t discuss these in depth, if you need to change how a method from a consuming class works by adding behavior before and/or after that method, check out method modifiers.</p>

<p>The third thing you might notice is the name of the package that I chose.
The only thing that limits what classes the role can be consumed by is the <code>requires</code> keyword.
However clearly this role is intended to work with functionality provided by Mojo::DOM and so this name is a good choice.</p>

<h2>Composing Roles</h2>

<p>Now that we know how to create a role, how is it used?
Well, let&#39;s continue with the prior example.</p>

devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles  view on Meta::CPAN

<p>There are three modules (only two on CPAN so far) that let you run javascript on pages via external processes.
<a href="https://metacpan.org/pod/Test::Mojo::Role::Phantom">Test::Mojo::Role::Phantom</a> and <a href="https://metacpan.org/pod/Test::Mojo::Role::Selenium">Test::Mojo::Role::Selenium</a> use <a href="http://phantomjs.org/">PhantomJS</a> and <a href=...
PhantomJS is abandoned however so <a href="https://github.com/jberger/Mojo-Chrome">Test::Mojo::Role::Chrome</a> is in development on my Github and will replace the PhantomJS role.</p>

<p>Note that several of these modules depend on a module named <a href="https://metacpan.org/pod/Test::Mojo::WithRoles">Test::Mojo::WithRoles</a> which is essentially obsolete at this point.
It can be safely ignored and authors can remove it from their module&#39;s dependencies when convenient.</p>

<p>Apart from testing, other roles include</p>

<ul>
<li><a href="https://metacpan.org/pod/Mojo::Log::Role::Clearable">Mojo::Role::Log::Clearable</a> allowing the Mojo::Log to cleanly change paths</li>
<li><a href="https://metacpan.org/pod/Mojo::DOM::Role::PrettyPrinter">Mojo::DOM::Role::PrettyPrinter</a> pretty prints Mojo::DOM documents</li>
<li><a href="https://metacpan.org/pod/Mojo::Collection::Role::UtilsBy">Mojo::Collection::Role::UtilsBy</a> adds <a href="https://metacpan.org/pod/List::UtilsBy">List::UtilsBy</a> methods to <a href="http://mojolicious.org/perldoc/Mojo/Collection">Moj...
<li><a href="https://metacpan.org/pod/distribution/Mojo-UserAgent-CookieJar-Role-Persistent/lib/Mojo/UserAgent/CookieJar/Role/Persistent.pod">Mojo::UserAgent::CookieJar::Role::Persistent</a> can store cookies from Mojo::UserAgent requests persistentl...
</ul>

<p>... as well as others.
And the list is sure to grow now that Mojo::Base can natively compose these roles.</p>

              </section>
              <small><p><a href="https://commons.wikimedia.org/w/index.php?curid=15179120">Image</a> © Jorge Royan / <a class="external free" href="http://www.royan.com.ar" rel="nofollow">http://www.royan.com.ar</a>, <a href="https://creativ...

devdata/https_mojolicious.io_blog_2017_12_16_day-16-the-secret-life-of-sessions  view on Meta::CPAN


<p>and visit <code>localhost:3000</code> you should see a counter that increments on each request.
That data is stored on the client (e.g. in the browser) between each request and is incremented on the server before sending it back to the client.
Each response is a new cookie with the new session data and a new cookie expiration time, <a href="http://mojolicious.org/perldoc/Mojolicious/Sessions#default_expiration">defaulting to one hour</a> from issue.
This also therefore implies that as long as you visit often enough (before any one cookie expires) and your data continues to validate against the secret, your session can last forever.</p>

<h2>Secret Security</h2>

<p>Now, one other thing you should see is that in your application&#39;s log output, you should have a message like</p>

<pre><code>Your secret passphrase needs to be changed
</code></pre>

<p>This happens because you are using the default secret for the application.
This default is just the name of the script, as you can see via the <a href="/blog/2017/12/05/day-5-your-apps-built-in-commands">eval command</a></p>

<pre><code>$ perl myapp.pl eval -V &#39;app-&gt;secrets&#39;
[
  &quot;myapp&quot;
]
</code></pre>

devdata/https_mojolicious.io_blog_2017_12_16_day-16-the-secret-life-of-sessions  view on Meta::CPAN

};

app-&gt;start;

</code></pre>

<p>If it finds a <code>secrets</code> parameter in your configuration, it will set it as the <code>secrets</code> on your application.
Since you have one in your new configuration file, it should set that property and the warning should go away.
Congratulations, you have a safer application already!</p>

<p>If sometime later, you suspect that someone has guessed your secret, or if your secret leaks out, you can change that secret and restart your application.
This will protect your application from malicious users.</p>

<p>For your clients, this will have the jarring effect that all existing sessions will be invalidated.
In the example application the counter would be reset.
If instead the session were being used to keep users logged in, they would suddenly be logged out.
If it was for tracking a shopping cart ... no more shopping cart.</p>

<p>This can actually be useful even if your secret is safe but you want to force-invalidate sessions for some other reason, like say your application was generating corrupt data or worse.
Generally, however, this is something you&#39;d like to avoid.</p>

devdata/https_mojolicious.io_blog_2017_12_16_day-16-the-secret-life-of-sessions  view on Meta::CPAN


</code></pre>

<p>So why isn&#39;t this recommended?
Because it would mean that each time you started the server you would get a new secret.
As with the case of changing your secret intentionally above, all existing sessions would be invalidated any time you wanted to reboot a server or restart the server process.
Additionally you could only use one server, any load balancing scenario would result in different secrets on different hosts, your users would randomly invalidate their sessions depending on which server they hit!</p>

<h2>Forward Secrecy</h2>

<p>Just as you have to change application passwords from time to time, so too you need to change your secret.
In a brute force scenario, a nefarious user could take one of their cookies and try to reverse engineer the secret that was used to generate it.</p>

<p>But wait!
You just said that changing the secret to prevent brute forcing will invalidate all of our sessions!</p>

<p>Remember when I pointed out that rather than being a single value, <code>secrets</code> was an array reference?
Well when Mojolicious generates a session cookie, it does so using the first value in the array reference.
However, when it validates session signatures, it will check them against each secret in the array.</p>

<p>So, say the time has come to rotate our secrets so we generate another</p>

devdata/https_mojolicious.io_blog_2017_12_16_day-16-the-secret-life-of-sessions  view on Meta::CPAN

    &#39;<span class="hljs-string">w8S4b+90CWwf</span>&#39;,
    &#39;<span class="hljs-string">yuIB7m88wS07</span>&#39;,
  ],
}
</code></pre>

<p>and restart the application.
Any requests with valid sessions will still work.
The reply they receive will contain a new session cookie, as always, but this time it will be issued using the new secret!</p>

<p>Requests issued by the old credentials will slowly be replaced by new ones as clients each make their first requests following the change.
Once you wait long enough that any valid session cookie would have expired, you can remove the old secret from the configuration and restart again.</p>

<h2>Restarting</h2>

<p>This is a good time to mention <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Hypnotoad"><code>hypnotoad</code></a>.
It is Mojolicious&#39; recommended production application server.
It has many of the same characteristics as the <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Pre-forking"><code>prefork</code></a> server but with some tuned settings and one killer feature, <a href="http://mojolicious.org/perld...

<p>Note that on native Windows, <code>hypnotoad</code> will not work.
That said, it works great on the new <a href="https://blogs.msdn.microsoft.com/wsl/">Windows Subsystem for Linux</a>!</p>

devdata/https_mojolicious.io_blog_2017_12_16_day-16-the-secret-life-of-sessions  view on Meta::CPAN

</code></pre>

<p>The really interesting thing happens when restarting a running application.
Say you&#39;ve rolled your secrets and want to restart the application to use it.
Simply run the command as before, just like when you started it up.</p>

<p>Any requests currently being served by the old server processes will continue to be served by them (up to some timeout).
Any new requests will be served by new processes using the new configuration.
You don&#39;t cut off any users in the process.</p>

<p>Actually <code>hypnotoad</code> can be used to zero downtime restart for more reasons than just configuration changes.
It can handle changes to your application, updating dependencies, or even upgrading your version of Perl itself!</p>

<p>For now though, we&#39;re just satisfied that clients are none the wiser that you rolled the application secret out from under them without losing any connections nor invalidating any sessions.</p>

              </section>
              <small><p><a href="https://commons.wikimedia.org/w/index.php?curid=54930070">Image</a> by <a class="external text" href="https://www.flickr.com/people/30478819@N08" rel="nofollow">Marco Verch</a> - <a class="external text" href="https:/...
</small>

              <p class="tags">
                <span>Tagged in </span>:
                  <a href="/blog/tag/advent/">advent</a>,

devdata/https_mojolicious.io_blog_2017_12_17_day-17-the-wishlist-app  view on Meta::CPAN

In the meantime however, you can see the application in the source for this <a href="https://github.com/MojoliciousDotIO/mojolicious.io/tree/master/blog/2017/12/17/day-17-the-wishlist-app/wishlist">article</a>.
To run it, you will need to install two additional modules, DBM::Deep and <a href="https://metacpan.org/pod/LinkEmbedder">LinkEmbedder</a>.</p>

<pre><code>$ cpanm Mojolicious DBM::Deep LinkEmbedder
</code></pre>

<h2>Layouts</h2>

<p>Most web sites have a defined style and layout between pages.
A header bar, a sidebar for navigation, a footer.
The content of each might change slightly between pages but the similarity is remarkable.</p>

<p>Do the developers copy and paste this logic between pages?
Certainly not!</p>

<p>The first tool of the trade is a layout template.
This is a template that will contain the results of rendering some inner template.
This will usually contain the outermost tags, like <code>&lt;html&gt;</code>, <code>&lt;head&gt;</code>, and <code>&lt;body&gt;</code>.
They will likely also establish any structure that exists on all of the pages, like navigation and sidebar sections.</p>

<p>Let&#39;s look at the layout that our wishlist application</p>

devdata/https_mojolicious.io_blog_2017_12_17_day-17-the-wishlist-app  view on Meta::CPAN

That is used when a user pastes a url that they want to add to their list.
LinkEmbedder will fetch that page and scrape it for metadata using several open protocols and falling back onto heuristics if possible.
It will then return the information and an short HTML representation of that resource.</p>

<h3>Routes</h3>

<p>The routes are mostly self explanatory, even if their code is not.
The <code>/login</code> and <code>/logout</code> handlers, for example.</p>

<p>There are two routes for <code>/add</code> a <code>GET</code> and a <code>POST</code>.
<code>GET</code> requests are safe and will not change data, in this case the request triggers LinkEmbedder to fetch the information which is then displayed.</p>

<h4>Adding Items</h4>

<p><img alt="Screen shot of the add items page" src="add.png"></p>

<pre><code class="hljs">% title &#39;<span class="hljs-string">Add an item</span>&#39;;
% layout &#39;<span class="hljs-string">default</span>&#39;;

% content_for &#39;<span class="hljs-string">head</span>&#39; =&gt; <span class="hljs-keyword">begin</span>
  &lt;style&gt;

devdata/https_mojolicious.io_blog_2017_12_17_day-17-the-wishlist-app  view on Meta::CPAN


<p>The template itself is the most complex in the application.
It includes three partial templates and places all of their content into the <code>sidebar</code> buffer.
It then looks up the user by virtue of that clever <code>user</code> helper and loops over their items.</p>

<p>The items are placed into a table, displaying the title and link to the item.
The third column&#39;s contents depends if the list is being shown is the user&#39;s own page or not.</p>

<p>If not, they are likely considering buying one of these gifts for their friend or family member.
They are given the option to mark an item as purchased or not.
This is done by calling the <code>/update</code> method, the result of which will change the item&#39;s status and re-render the page.o</p>

<p>If it is their own page, they don&#39;t want to have the surprise spoiled see that someone has bought their present.
So we don&#39;t show the purchase state.
However perhaps they have changed their mind and no longer want that item.
In that case, they are presented with a remove button which calls to the <code>/remove</code> route.</p>

<p>Finally let&#39;s look at those last two partials.
There is a sidebar list of the users, so you can see everyone&#39;s list.</p>

<pre><code class="hljs">&lt;div class=&quot;<span class="hljs-string">panel panel-default</span>&quot;&gt;
  &lt;div class=&quot;<span class="hljs-string">panel-heading</span>&quot;&gt;
    Users&#39;<span class="hljs-string"> Lists</span><span class="hljs-string">
</span><span class="hljs-string">  &lt;/div&gt;</span><span class="hljs-string">
</span><span class="hljs-string">  &lt;div class=&quot;panel-body&quot;&gt;</span><span class="hljs-string">

devdata/https_mojolicious.io_blog_2017_12_19_day-19-make-your-app-installable  view on Meta::CPAN

  <link href="/theme/css/default.css" rel="stylesheet">
  <link href="/theme/css/layout.css" rel="stylesheet">
  <link href="/theme/css/media-queries.css" rel="stylesheet">
  <link href="/theme/css/statocles.css" rel="stylesheet">

  <!-- twitter and opengraph -->
  <meta content="summary" name="twitter:card">
      <meta content="@joelaberger" name="twitter:creator">
  <meta content="https://mojolicious.io/blog/2017/12/19/day-19-make-your-app-installable/" property="og:url">
  <meta content="Day 19: Make Your App Installable" property="og:title">
    <meta content="A few simple changes to make your application installable." property="og:description">
    <meta content="https://mojolicious.io/blog/2017/12/19/day-19-make-your-app-installable/container_ship.jpg" property="og:image">
    <meta content="summary_large_image" name="twitter:card">

  <script src="/theme/js/modernizr.js"></script>

      <link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/sunburst.min.css" rel="stylesheet">

  <title>Day 19: Make Your App Installable - mojolicious.io</title>
  <meta content="Joel Berger" name="author">
  <meta content="Statocles 0.093" name="generator">

devdata/https_mojolicious.io_blog_2017_12_19_day-19-make-your-app-installable  view on Meta::CPAN

              <div class="post-thumb">
                <!-- theme suggests 1300x500 -->
                <img alt="Container ship loading at the dock" src="/blog/2017/12/19/day-19-make-your-app-installable/container_ship.jpg">
              </div>

            <div class="post-content">

              <section id="section-1">
                  <p>Thus far we have always run our applications from the local directory.
That is usually the project root directory and/or the repository checkout.
But did you know that with only a few changes you can make your application installable like other Perl modules?</p>

<p>While, you must do this if you want to upload your application to CPAN, even if you don&#39;t intend to do that, it still has benefits.
You can install the application on your personal computer, especially if you want to be able to run the script while in other directories.
Having an installable module also means that you can use a so-called &quot;DarkPAN&quot; and related tools to build yourself a local &quot;CPAN&quot;.
If you have multiple Perl modules at your company (or as part of any project) using a DarkPAN can ease integration and deployment immensely!
N.B. there is even a DarkPAN tool written using Mojolicious called <a href="https://metacpan.org/pod/App::opan">opan</a>.</p>

<p>And hey if you needed even more more reason, it cleans up your project root directory somewhat too!</p>

              </section>

devdata/https_mojolicious.io_blog_2017_12_19_day-19-make-your-app-installable  view on Meta::CPAN

  unshift @{ $app-&gt;renderer-&gt;paths }, $templates;
}
</code></pre>

<p>Note that you could use that kind of process to allow other configured files to be relative to the home.
The application home is a great place to put data like a sqlite database; the sqlite database file seen earlier, which as show had to be an absolute path.
Indeed such a transform exists already exists in the Wishlist app but was omitted above for clarity.</p>

<h2>In Conclusion</h2>

<p>I have made some of these changes to the <a href="https://github.com/jberger/Wishlist/compare/blog_post/sqlite_model...blog_post/installable">Wishlist App</a>.
You&#39;ll see that it it really isn&#39;t much to do.</p>

<p>You also see that I only used as much of these instructions as I needed; you can do the same.
There is no magic in any of what you&#39;ve seen (other than perhaps File::Share).
If you don&#39;t need to think about theming or customizing the environment variable, then don&#39;t worry about it.
But if you find yourself in that situation, you&#39;ll know you can make such features available to your users.</p>

<p>And hey, if it is a useful application, consider uploading it to CPAN.
Though I warn you, once you start contributing to CPAN it can be addictive!</p>

devdata/https_mojolicious.io_blog_2017_12_20_day-20-practical-testing  view on Meta::CPAN

  ],
}, &#39;<span class="hljs-string">correct initial user state</span>&#39;;

done_testing;

</code></pre>

<p><small><a href="https://github.com/jberger/Wishlist/blob/blog_post/practical_testing/t/model.t">t/model.t</a></small></p>

<p>When called this way the passed hashref is loaded into the configuration rather than any configuration file.
Because of the way the <a href="https://github.com/jberger/Wishlist/blob/blog_post/practical_testing/lib/Wishlist.pm#L20-L26"><code>sqlite</code></a> attribute initializer was coded, the Mojo::SQLite special literal <code>:temp:</code> is passed thro...
Now I would never suggest that you write any code into your application that is specific to testing, however it is entirely reasonable to code around special literals that someone might need.
You could of course start a Wishlist server using a temporary database.</p>

<p>SQLite&#39;s in-memory (and Mojo::SQLite&#39;s on-disk temporary) databases are really handy for testing because they are automatically testing in isolation.
You don&#39;t have to worry about overwriting the existing database nor clearing the data at the end of your test.
Further, you can run your tests in <a href="https://metacpan.org/pod/Test::Harness#j&lt;n&gt;">parallel</a> to get a nice speedup in large test suites.</p>

<p>For databases that require a running server you have to be a little more careful, however isolated testing is still very possible.
For example, in Mojo::Pg you can set a <a href="http://mojolicious.org/perldoc/Mojo/Pg#search_path"><code>search_path</code></a> which isolates your test.</p>

devdata/https_mojolicious.io_blog_2017_12_21_day-21-virtually-a-lumberjack  view on Meta::CPAN

interface and opens the device to read the packets, which makes this much
easier.
Doing so allows us to ask others who have HMDs to send us these logs, so we
can add driver support for devices none of the team have access to!
Otherwise, we use something else to open the device and read data and <code>tshark</code>
to capture and output the packet data.</p>

<pre><code>tshark -i usbmon1 -Y &#39;usb.src == &quot;1.22.1&quot;&#39; -T fields -e usb.capdata
</code></pre>

<p>You may need to change your buffering to line-mode. You can do so by prefixing
<code>stdbuf -oL</code> like so:</p>

<pre><code>stdbuf -oL tshark ...
</code></pre>

<p>This (and OpenHMD-Dumper) will output data that looks like this:</p>

<pre><code>20:d6:00:1a:e0:4a:fe:d5:ff:12:00:66:00:be: ...
20:c2:00:3c:e0:16:fe:d1:ff:04:00:62:00:d5: ...
20:c2:00:3c:e0:16:fe:d1:ff:04:00:62:00:d5: ...

devdata/https_mojolicious.io_blog_2017_12_22_day-22-how-to-build-a-public-rest-api  view on Meta::CPAN

generated, so let&#39;s see if we can send/receive any data to the server. To try
it out, we use the &quot;openapi&quot; sub command which was installed with
<a href="https://metacpan.org/pod/OpenAPI::Client">OpenAPI::Client</a>.</p>

<p>In this first example we try to send invalid body data using the <code>-c</code> switch:</p>

<pre><code>$ MOJO_LOG_LEVEL=info ./script/my_app openapi /api echo -c &#39;[42]&#39;
{&quot;errors&quot;:[{&quot;message&quot;:&quot;Expected object - got array.&quot;,&quot;path&quot;:&quot;\/body&quot;}]}
</code></pre>

<p>This next example should succeed, since we change from sending an array to
sending an object, as described in the API specification:</p>

<pre><code>$ MOJO_LOG_LEVEL=info ./script/my_app openapi /api echo -c &#39;{&quot;age&quot;:42}&#39;
{&quot;age&quot;:42}
</code></pre>

<p>Yay! We see that the same input data was echoed back to us, without any error
message. Mission accomplished!</p>

<h2>See also</h2>

devdata/https_mojolicious.io_blog_2017_12_23_day-23-one-liners-for-fun-and-profit  view on Meta::CPAN

(If you have a recent enough Perl, you can also use signatures on your functions automagically too.)</p>

<pre><code>perl -Mojo -E &#39;a(&quot;/&quot; =&gt; sub { $_-&gt;render(text =&gt; scalar localtime) })-&gt;start&#39; get /
</code></pre>

<p>Since all the commands work, using the Lite app and the <code>get</code> command together can mean that you see the results of a request to your one-liner application right there on your terminal!</p>

<p>I use this functionality all the time to quickly demonstrate some concept; sometimes to others or sometimes to myself.
What happens if I set this stash parameter?
Will a route condition do what I expect?
Indeed the Mojolicious core team members often make one-liner applications to paste into IRC when we want to reproduce some bug or discuss some change.</p>

<h3>Benchmarking</h3>

<p>And speaking of development, there is one more ojo function, and it is quite unlike the others.
The <code>n</code> function takes a block of code to run and optionally a number of times to run it and the function will output timing statistics over the runs.
The heavy lifting here is done by the Perl core <a href="https://metacpan.org/pod/Benchmark">Benchmark</a> module.</p>

<p>Say the Mojolicious core team is considering a change to the very performance sensitive Mojo::DOM parser.
We can take a baseline and then make our changes and each time run something like</p>

<pre><code>perl -Ilib -Mojo -E &#39;my $body = g(&quot;html.spec.whatwg.org&quot;)-&gt;body; n { x $body } 10&#39;
</code></pre>

<p>This fetches the rather large HTML document that defines HTML itself and then parses it 10 times.
The more runs, the more consistent your data should be since variations are averaged out.
Note especially how easily the fetching is excluded while what we care about is included.
On my laptop this gives the output.</p>

<pre><code>29.3775 wallclock secs (29.11 usr +  0.26 sys = 29.37 CPU) @  0.34/s (n=10)
</code></pre>

<p>Knowing that data taken with and without proposed changes we can have a better idea of the performance gains or impacts from that change.
While there is no magic in this function, the ease-of-use of the benchmarker means we are actually likely to use it, even for what may seem like small and insignificant changes.
This is a major reason for Mojolicious&#39; consistently blazing speeds.</p>

<h2>Conclusion</h2>

<p>Making <code>ojo</code> one-liners can be great to experiment with new concepts, demonstrate problems, fetch and work with data, and many other tasks.
You might use them in non-web one-liners that need JSON or Data::Dumper or perhaps MMojo::Collection for chaining.
(Speaking of chaining, for bonus points, check out <a href="https://metacpan.org/pod/ojoBox">ojoBox</a> for <a href="https://metacpan.org/pod/Mojo::Autobox">autoboxing Perl types</a>, making even cooler chains!)</p>

<p>These one-liners are not going to be everyone&#39;s cup of tea.
If these don&#39;t seem like your&#39;s you can completely ignore them.</p>

devdata/https_mojolicious.io_blog_2017_12_24_day-24-release-and-wrap-up  view on Meta::CPAN


<p>The internet has made so many amazing things possible.
Old friendships are kept alive.
Personal photographs can be stored forever and shared with friends.
Rare items can be discussed, found, and purchased.
News can spread as fast as fingers can type them.</p>

<p>But for all this ease and convenience there is a price.
Personal data is being taken, mined, and sold.
People are buying products that require internet connections but whose manufacturers will drop support before the hardware fails.
Statements you make and pictures you share will live on on the internet forever, even if you change.</p>

<h3>Fighting Back</h3>

<p>I would never say that the bad outweighs the good, but I do wish people would be more intentional about these types of choices online.
Yet that almost cannot happen until they have alternatives that they control.
To that end I have been trying in the past year to start to take control of my digital life where possible.
I have deployed <a href="https://nextcloud.com/">NextCloud</a> on a private server to keep my files and share with people I choose.
I wrote an application called <a href="https://github.com/jberger/CarPark">CarPark</a> to control my garage door via a RaspberryPi and even spoke about it at <a href="https://www.youtube.com/watch?v=aJc5yYONBBc">The Perl Conference</a>; it isn&#39;t ...

<p>And that brings us to the <a href="https://github.com/jberger/Wishlist">Wishlist</a> application.



( run in 0.396 second using v1.01-cache-2.11-cpan-5dc5da66d9d )