NAME

CatalystX::RequestModel::DoesRequestModel - Role to provide request model API

SYNOPSIS

Generally you will apply this role via CatalystX::RequestModel

package Example::Model::AccountRequest;

use Moose;
use CatalystX::RequestModel;

extends 'Catalyst::Model';
namespace 'person';
content_type 'application/x-www-form-urlencoded';

has username => (is=>'ro', property=>{always_array=>1});  
has first_name => (is=>'ro', property=>1);
has last_name => (is=>'ro', property=>1);
has notes => (is=>'ro', property=>+{ expand=>'JSON' });

See CatalystX::RequestModel for a more general overview.

DESCRIPTION

A role that gives a Catalyst::Model the ability to indicate which of its attributes should be consider request model data, as well as additional need meta data so that we can process it properly.

Since we need to wrap has you should never apply this role manually but rather instead use CatalystX::RequestModel to apply it for you. If you need to customize this role you will also need to subclass CatalystX::RequestModel and have that new subclass apply you custom role. Please ping me if you really need this since I guess we could change CatalystX::RequestModel to make it easier to supply a custom role, just let me know your use case.

METHODS

This class defines the following public API

nested_params

Returns all the attributes marked as request properties in the form of a hashref. If any of the properties refer to an array or indexed value, or an object, we automatically follow that to return all the property data below.

Attributes that are empty will be left out of the return data structure.

Easiest way to get all your data but then again you get a structure that is very tightly tied to your request model.

as_data

my $data = $object->as_data(@namespace, $spec);

This method serializes the object into a data structure (hash reference) based on the provided specification. It allows for selective extraction of object properties and supports nested structures.

@namespace

An optional list of method names to call on the object to navigate to the desired sub-object. Each method in the namespace should return an object or value that the next method in the namespace can be called on.

$spec

An array reference that defines which properties to include in the serialized data. Each element in the array can be either a string (property name) or a hash reference (property name and sub-specification).

The method performs the following steps:

  1. Separates the namespace from the data specification pattern.

  2. Retrieves property information as a hash.

  3. If a namespace is provided, navigates through the object structure to the desired sub-object.

  4. Iterates over the specification array and extracts the corresponding data from the object.

The method handles properties that are arrays, objects, or plain scalar values. It also respects the `omit_empty` attribute for properties, skipping them if they are empty and `omit_empty` is set to true.

Returns a hash reference containing the serialized data.

Examples

Basic Usage
# Example 1: Converting a flat structure of incoming parameters
# Imagine these are parameters from an HTTP request (e.g., form submission)
my %incoming_params = (
  property1 => 'Alice',
  property2 => 'Engineer',
);

# Create the request model object with the incoming parameters
my $object = My::RequestModel->new(%incoming_params);

# Convert the request model into a simple hash reference.
# This will only include 'property1' and 'property2' from the object.
my $data = $object->as_data(['property1', 'property2']);

use Data::Dumper;
print "Flat conversion:\n", Dumper($data);

$VAR1 = {
          'property1' => 'Alice',
          'property2' => 'Engineer'
        };

# Example 2: Converting a nested structure
# Here, the incoming parameters include a nested hash for address details.
my %incoming_nested = (
  property1 => 'Alice',
  property2 => 'Engineer',
  address   => {
    street => '123 Main St',
    city   => 'Anytown',
  },
);

# Re-create the request model object with nested parameters.
my $nested_object = My::RequestModel->new(%incoming_nested);

# Convert into a hash reference.
# The first argument 'address' directs as_data to navigate into the nested address object.
# The spec ['street', 'city'] lists the properties to extract from that nested object.
my $nested_data = $nested_object->as_data([
  'property1', 'property2',   # top-level properties
  {'address' => ['street', 'city'] }
]
);

print "Nested conversion:\n", Dumper($nested_data);

$VAR1 = {
          'property1' => 'Alice',
          'property2' => 'Engineer',
          'address' => {
                         'street' => '123 Main St',
                         'city' => 'Anytown'
                       }
        };
Nested Structures
my $data = $object->as_data('sub_object', [
  'property1',
  { 'nested_property' => ['sub_property1', 'sub_property2'] }
]);

This will navigate to the 'sub_object' within the main object and serialize 'property1' and 'nested_property', where 'nested_property' includes 'sub_property1' and 'sub_property2'.

get

Accepts a list of attributes that refer to request properties and returns their values. In the case when the attribute listed has no value, you will instead get an undef.

EXCEPTIONS

This class can throw the following exceptions:

Invalid Request Content Body

If we can't create an instance of the request model we throw a CatalystX::RequestModel::Utils::BadRequest. This will get interpretated as an HTTP 400 status client error if you are using CatalystX::Errors.

AUTHOR

See CatalystX::RequestModel.

COPYRIGHT

See CatalystX::RequestModel.

LICENSE

See CatalystX::RequestModel.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 438:

You forgot a '=back' before '=head2'