Catalyst::TraitFor::Request::QueryFromJSONY - Handle complex query parameters using JSONY


For Catalyst v5.90090+

    package MyApp;

    use Catalyst;


For Catalyst older than v5.90090

    package MyApp;

    use Catalyst;
    use CatalystX::RoleApplicator;


In a controller:

    package MyApp::Controller::Example;

    use Moose;
    use MooseX::MethodAttributes;
    use Data::Dumper;

    sub echo :Local {
      my ($self, $c) = @_;
      $c->res->body( Dumper $c->req->query_data );

Example test case:

    ok my $res = request GET "/example/echo?q={'id':100,'age':['>',10]}";
    is_deeply eval $res->content, {
      'id' => 100,
      'age' => [ '>', 10 ]


This is an early access release of this module. Experimentation as to the best approach is ongoing.

There are cases when you'd like to express complex data structures in your URL query part (tha bit after the '?'). There's been a number of attempts at this, this module is yet another. In this version we allow for a query parameter 'q' to be a JSONY serialized string (JSONY is basically JSON relaxed a bit to reduce a bit of verbosity and smooth over common errors that are more pedantic that useful). We deserialize this string and place its value in 'query_data'.

This only happens if you request the query_data attribute, so there's no overhead to simply having this installed.

You can have other 'classic' query parameters mixed in with the 'q' parameter, but for no only 'q' is deserialized. The original value of 'q' is preserved in the original query_parameter method.


This role defines the following methods.

query_data (?@query_params, ?\%options)

For each item in @query_params that exists in $request->query_parameters deserialize using JSONY and return the data references (could be a hashref, or arrayref depending on the query construction.

If no @query_params are submitted, assume 'q' as the default.

The %options hash allows you to set callback to handle exceptional conditions. All callbacks get invoked with two parameters, the current $request object, and the name of the query parameter that caused the condition. For example the follow substitutes the string '[]' when a $key is missing from %{$c->req->query_parameters}:

    $c->req->query_data(qw/a b c/, +{ 
      param_missing => sub {
        my ($req, $key) = @_;
        return '[]';

Currently we support the following exceptional conditions:


Gets $request, $key

This is the callback that gets invoked when $c->req->query_paramerters->{$key} does not exist. The default behavior is to return an empty string, which JSONY deserialized into a hashref. This allows you to request parameters that are optional and not product an exception.


Gets $request, $key, $error_message

This callback is called when JSONY throws an exception trying to parse the value associated with $key. The default is to just rethrow the error.


John Napiorkowski


Catalyst, Catalyst::Request, JSONY


Copyright 2015, John Napiorkowski

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.