[dancer-users] Methods Of retrieving request parameters

Warren Young wyml at etr-usa.com
Tue Jul 12 21:27:27 BST 2016


On Jul 12, 2016, at 1:41 PM, John J. McDermott, CPLP <jjm at jkintl.com> wrote:
> 
> Let's say I have an app that can generate two kinds of output.  It is a front-end to a database It can be used with a JSON interface or it can present HTML as a traditional web page.

Perfectly fine so far.

> I *could* add a /html element to the path to say "output as html" but it would seldom -- if ever -- be used. I *could* add a checkbox to the web form so it would return JSON but it is unlikely a normal person would want that.

Do you know a strong functional programming language?  I don’t mean FP in the way that JavaScript is a Scheme dialect and therefore FP, or even in the way that Perl is FP as laid out in Dominus’ “Higher-Order Perl.”  I mean FP as in Haskell, the ML family, Erlang, etc.

These languages teach you the value of thinking of functions in the mathematical sense, which is that any function called with a given set of arguments should always return the same result.  Another way of saying the same thing is that functions should not have side effects.

It is impossible to avoid all side effects in any practical program not doing pure mathematics, but we can minimize and restrict the scope of these side effects by thinking hard about where the boundaries should be.  Strong FP languages sensitize you to this way of thinking.

In the context of this debate, the principles of tightly-scoped side effects and referential transparency tell us that if you should not have a a Dancer route that returns HTML in one context and JSON in another.  Either the route must differ somehow or the parameters must differ.

My preference is to put all JSON-returning Dancer routes under /api, then make all other routes return HTML.  (That’s a simplification.  My current app also has /pdf for the routes that return dynamically-generated PDFs, for example.)

Where the HTML-returning routes need data returned by the JSON API, either:

1. Call the internal JSON-returning route handler from the HTML route handler and use its data to construct the HTML; or

2. Call back into the API from the client side via JS and construct HTML from the returned JSON data there.

An example of alternative 1 is:

    sub getSomeData {   … used below …    }

    get '/foo' => {  # because not under /api, returns HTML
         # Do stuff here
         # ...

         # Okay, we’re ready to return our page
         return template '/foo' => {
              oneElement     => getSomeData(param 'bar'),
              anotherElement => $variableComputedAbove,
         }
    };

    prefix '/api' => {
        prefix '/some' => {
            get '/data' => \&getSomeData
        };
    };

Here we have two routes, one returning HTML and one returning JSON, the first of which is implemented in terms of the second.  Because of Dancer's automatic serializers, getSomeData() can return a normal Perl data structure that can either be consumed directly by the template used in the HTML case or be serialized to JSON for consumption on the client side via JS code.

Note the use of code references here to allow the HTML route handler to call the JSON route handler.

You can read more about this style of development in a series of articles I wrote for the fizzled Dancer 2015 Advent Calendar:

   https://goo.gl/u900Ii

A lesser design principle is that, to the greatest extent practical, you should push most of the code into the JSON side to reduce code duplication.  The HTML/JS client-side code can also consume JSON, but the JSON API has little use for HTML.

To drag this back onto the topic of this particular thread, it is immaterial in my view whether the values passed to the Dancer route come from the URL’s query parameters, are defined as part of the route, or are passed in via a POST call in the request body.  Parameters are parameters, and a properly-written Dancer route handler should return the same data regardless of the exact mechanism used to pass those parameters.


More information about the dancer-users mailing list