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
/mf URLs we've been using in examples so far should
be served by a
mf.js in several different purpose-driven JS files, compiled
mf.js by RequireJS or a similar tool.
Dancer2 Deployment Guide
recommends running your app behind a front-end reverse proxy server
such as nginx or Apache's
mod_proxy. I strongly encourage you to do
this, even in development.
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.
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
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.
You might want to take this a step further, in fact. Instead of merely
disabling Dancer's static file handler in your
config.yml file for
the duration of a single test session, you could instead disable it
permanently in your
environments/development.yml file to ensure that
you find and fix such problems in development, before you deploy to
I cannot recommend doing this permanently at the
environments/production.yml levels, because I have occasionally found
it useful to be able to put random files into my app's
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
ad hoc 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.
I can offer a related bit of advice here: if you must change the
log_level setting of a Dancer app running in a public-facing
production setting, never raise it to
core, at least not for very
long. Dancer logs all URLs retrieved at that level, and the default
production.yml 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.
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
In the next part of this article series, we will discover the REST API that was hidden inside this monolithic web app the whole time.
This article has been written by Warren Young for the Perl Dancer Advent Calendar 2016.
© 2015, 2016 by Educational Technology Resources, licensed under Creative Commons Attribution-ShareAlike 4.0