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

Catalyst::ActionRole::RequestModel - Inflate a Request Model

SYNOPSIS

    package Example::Controller::Account;

    use Moose;
    use MooseX::MethodAttributes;

    extends 'Catalyst::Controller';

    sub root :Chained(/root) PathPart('account') CaptureArgs(0)  { }

      sub update :POST Chained('root') PathPart('') Args(0) Does(RequestModel) RequestModel(AccountRequest) {
        my ($self, $c, $request_model) = @_;
        ## Do something with the $request_model
      }

    __PACKAGE__->meta->make_immutable;

DESCRIPTION

Moves creating the request model into the action class execute phase. The following two actions are essentially the same in effect:

    sub update :POST Chained('root') PathPart('') Args(0) Does(RequestModel) RequestModel(AccountRequest) {
      my ($self, $c, $request_model) = @_;
      ## Do something with the $request_model
    }

    sub update :POST Chained('root') PathPart('') Args(0) {
      my ($self, $c) = @_;
      my $request_model = $c->model('AccountRequest');
      ## Do something with the $request_model
    }

The main reason for moving this into the action attributes line is the thought that it allows us to declare the request model as meta data on the action and in the future we will be able to introspect that meta data at application setup time to do things like generate an Open API specification. Also, if you have several request models for the endpoint you can declare all of them on the attributes line and we will match the incoming request to the best request model, or throw an exception if none match. So if you have more than one this saves you writing that boilerplate code to chose and to handled the no match conditions.

You might also just find the code neater and more clean reading. Downside is for people unfamiliar with this system it might increase learning curve time.

METHOD ATTRIBUTES

This action role defines the following method attributes

RequestModel

Should be the name of a Catalyst::Model subclass that does <CatalystX::RequestModel::DoesRequestModel>. You may supply more than one value to handle different request content types (the code will match the incoming content type to an available request model and throw an CatalystX::RequestModel::Utils::InvalidContentType exception if none of the available models match.

Example of an action with more than one request model, which will be matched based on request content type.

    sub update :POST Chained('root') PathPart('') Args(0) Does(RequestModel) RequestModel(AccountRequestForm) RequestModel(AccountRequestJSON) {
      my ($self, $c, $request_model) = @_;
      ## Do something with the $request_model
    }

Also, if more than one model matches, you'll get an instance of each matching model.

AUTHOR

See CatalystX::RequestModel.

COPYRIGHT

See CatalystX::RequestModel.

LICENSE

See CatalystX::RequestModel.