The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

CatalystX::RequestModel::ContentBodyParser::JSON

SYNOPSIS

    TBD

DESCRIPTION

Given a valid JSON request body, parse it and inflate request models as defined or throw various exceptions otherwise. for example given the following nested request models:

    package Example::Model::API::AccountRequest;

    use Moose;
    use CatalystX::RequestModel;

    extends 'Catalyst::Model';
    namespace 'person';
    content_type 'application/json';

    has username => (is=>'ro', property=>1);  
    has first_name => (is=>'ro', property=>1);
    has last_name => (is=>'ro', property=>1);
    has profile => (is=>'ro', property=>+{model=>'API::AccountRequest::Profile' });
    has person_roles => (is=>'ro', property=>+{ indexed=>1, model=>'API::AccountRequest::PersonRole' });
    has credit_cards => (is=>'ro', property=>+{ indexed=>1, model=>'API::AccountRequest::CreditCard' });

    __PACKAGE__->meta->make_immutable();

    package Example::Model::API::AccountRequest::Profile;

    use Moose;
    use CatalystX::RequestModel;

    extends 'Catalyst::Model';

    has id => (is=>'ro', property=>1);
    has address => (is=>'ro', property=>1);
    has city => (is=>'ro', property=>1);
    has state_id => (is=>'ro', property=>1);
    has zip => (is=>'ro', property=>1);
    has phone_number => (is=>'ro', property=>1);
    has birthday => (is=>'ro', property=>1);
    has registered => (is=>'ro', property=>+{ boolean=>1 });

    __PACKAGE__->meta->make_immutable();

    package Example::Model::API::AccountRequest::PersonRole;

    use Moose;
    use CatalystX::RequestModel;

    extends 'Catalyst::Model';

    has role_id => (is=>'ro', property=>1);

    __PACKAGE__->meta->make_immutable();

    package Example::Model::API::AccountRequest::CreditCard;

    use Moose;
    use CatalystX::RequestModel;

    extends 'Catalyst::Model';

    has id => (is=>'ro', property=>1);
    has card_number => (is=>'ro', property=>1);
    has expiration => (is=>'ro', property=>1);

    __PACKAGE__->meta->make_immutable();

And the following POSTed JSON request body:

    {
      "person":{
        "username": "jjn",
        "first_name": "john",
        "last_name": "napiorkowski",
        "profile": {
          "id": 1,
          "address": "1351 Miliary Road",
          "city": "Little Falls",
          "state_id": 7,
          "zip": "42342",
          "phone_number": 6328641827,
          "birthday": "2222-01-01",
          "registered": false        
        },
        "person_roles": [
          { "role_id": 1 },
          { "role_id": 2 }
        ],
        "credit_cards": [
          { "id":100, "card_number": 111222333444, "expiration": "2222-02-02" },
          { "id":200, "card_number": 888888888888, "expiration": "3333-02-02" },
          { "id":300, "card_number": 333344445555, "expiration": "4444-02-02" }
        ]
      }
    }

Will inflate a request model that provides:

    my $request_model = $c->model('API::AccountRequest');
    Dumper $request_model->nested_params;

    +{
      'person_roles' => [
                          {
                            'role_id' => 1
                          },
                          {
                            'role_id' => 2
                          }
                        ],
      'profile' => {
                     'address' => '1351 Miliary Road',
                     'birthday' => '2222-01-01',
                     'id' => 1,
                     'state_id' => 7,
                     'phone_number' => 6328641827,
                     'registered' => 0,
                     'zip' => '42342',
                     'city' => 'Little Falls'
                   },
      'credit_cards' => [
                          {
                            'card_number' => '111222333444',
                            'expiration' => '2222-02-02',
                            'id' => 100
                          },
                          {
                            'id' => 200,
                            'card_number' => '888888888888',
                            'expiration' => '3333-02-02'
                          },
                          {
                            'id' => 300,
                            'card_number' => '333344445555',
                            'expiration' => '4444-02-02'
                          }
                        ],
      'first_name' => 'john',
      'username' => 'jjn',
      'last_name' => 'napiorkowski' 
    };    

VALUE PARSER CONFIGURATION

This parser defines the following attribute properties which effect how a value is parsed.

flatten

Defaults to false. If enabled it will flatten an array value to a scalar which is the value of the last item in the list. Probably not useful in JSON, it's more of a hack for HTML Form posts, which makes it hard to be consistent in array versus scalar values, but no reason to not offer the feature if you need it.

always_array

Similar to flatten but opposite, it forces a value into an array even if there's just one value. Also defaults to FALSE.

EXCEPTIONS

See CatalystX::RequestModel::ContentBodyParser for inherited exceptions.

Invalid JSON Content Body

If the JSON in the request content body is invalid, we throw a CatalystX::RequestModel::Utils::InvalidJSON exception.

AUTHOR

See CatalystX::RequestModel.

COPYRIGHT

See CatalystX::RequestModel.

LICENSE

See CatalystX::RequestModel.