# NAME

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

# SYNOPSIS

For [Catalyst](https://metacpan.org/pod/Catalyst) v5.90090+

    package MyApp;

    use Catalyst;

    MyApp->request_class_traits(['Catalyst::TraitFor::Request::QueryFromJSONY']);
    MyApp->setup;

For [Catalyst](https://metacpan.org/pod/Catalyst) older than v5.90090

    package MyApp;

    use Catalyst;
    use CatalystX::RoleApplicator;

    MyApp->apply_request_class_roles('Catalyst::TraitFor::Request::QueryFromJSONY');
    MyApp->setup;

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 ]
    };

# DESCRIPTION

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](https://metacpan.org/pod/JSONY) serialized string ([JSONY](https://metacpan.org/pod/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.

# METHODS

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](https://metacpan.org/pod/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:

### param\_missing

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.  

### parse\_error

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.

# AUTHOR

John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)

# SEE ALSO

[Catalyst](https://metacpan.org/pod/Catalyst), [Catalyst::Request](https://metacpan.org/pod/Catalyst::Request), [JSONY](https://metacpan.org/pod/JSONY)

# COPYRIGHT & LICENSE

Copyright 2015, John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)

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