Web-ComposableRequest
view release on metacpan or search on metacpan
lib/Web/ComposableRequest.pm view on Meta::CPAN
isa => Object,
default => sub { $_[0]->config_class->new($_[0]->config_attr) },
init_arg => undef;
has 'config_attr' =>
is => 'ro',
isa => HashRef|Object|Undef,
init_arg => 'config';
has 'config_class' =>
is => 'lazy',
isa => NonEmptySimpleStr,
default => sub {
my $base = __PACKAGE__ . '::Config';
my @roles = list_config_roles;
return $base unless @roles > 0;
return Moo::Role->create_class_with_roles($base, @roles);
};
has 'request_class' =>
is => 'lazy',
isa => NonEmptySimpleStr,
default => sub {
my $self = shift;
my $base = __PACKAGE__ . '::Base';
my $conf = $self->config_attr or return $base;
my $dflt = { request_class => $base, request_roles => [] };
my $attr = {};
merge_attributes $attr, $conf, $dflt, [keys %{$dflt}];
my @roles = @{$attr->{request_roles}};
return $attr->{request_class} unless @roles > 0;
@roles = map { (first_char $_ eq '+')
? substr $_, 1 : __PACKAGE__ . "::Role::${_}" } @roles;
return Moo::Role->create_class_with_roles($attr->{request_class}, @roles);
};
sub new_from_simple_request {
my ($self, $opts, @args) = @_;
my $attr = { %{ $opts // {} } };
my $request_class = $self->request_class; # Trigger role application
$attr->{config} = $self->config; # Composed after request_class
$attr->{env } = pop @args if @args and is_hashref $args[-1];
$attr->{params} = pop @args if @args and is_hashref $args[-1];
my $query = $attr->{env}->{'Web::Dispatch::ParamParser.unpacked_query'};
$attr->{params} = $query if $query;
for my $arg (grep { defined && length } @args) {
if (blessed $arg) { $attr->{upload} = $arg }
else {
push @{ $attr->{args} //= [] }, map { trim $_ } split m{ / }mx, $arg;
}
}
return $request_class->new($self->buildargs->($self, $attr));
}
1;
__END__
=pod
=encoding utf-8
=begin html
<a href="https://travis-ci.org/pjfl/p5-web-composablerequest"><img src="https://travis-ci.org/pjfl/p5-web-composablerequest.svg?branch=master" alt="Travis CI Badge"></a>
<a href="https://roxsoft.co.uk/coverage/report/web-composablerequest/latest"><img src="https://roxsoft.co.uk/coverage/badge/web-composablerequest/latest" alt="Coverage Badge"></a>
<a href="http://badge.fury.io/pl/Web-ComposableRequest"><img src="https://badge.fury.io/pl/Web-ComposableRequest.svg" alt="CPAN Badge"></a>
<a href="http://cpants.cpanauthors.org/dist/Web-ComposableRequest"><img src="http://cpants.cpanauthors.org/dist/Web-ComposableRequest.png" alt="Kwalitee Badge"></a>
=end html
=head1 Name
Web::ComposableRequest - Composable request class for web frameworks
=head1 Synopsis
use Web::ComposableRequest;
# List the roles to be applied to the request object base class
my $config = {
prefix => 'my_app',
request_roles => [ 'L10N', 'Session', 'Cookie', 'JSON', 'Static' ], };
# Construct a request object factory
my $factory = Web::ComposableRequest->new( config => $config );
# Request data provided by the web framework
my $args = 'arg1/arg2/arg_3';
my $query = { mid => '123_4' };
my $cookie = 'my_app_cookie1=key1%7Eval1%2Bkey2%7Eval2; '
. 'my_app_cookie2=key3%7Eval3%2Bkey4%7Eval4';
my $input = '{ "key": "value_1" }';
my $env = { CONTENT_LENGTH => 20,
CONTENT_TYPE => 'application/json',
HTTP_COOKIE => $cookie,
HTTP_HOST => 'localhost:5000',
PATH_INFO => '/Getting-Started',
'psgi.input' => IO::String->new( $input ),
'psgix.session' => {},
};
# Construct a new request object
my $req = $factory->new_from_simple_request( {}, $args, $query, $env );
=head1 Description
Composes a request class from a base class plus a selection of applied roles
( run in 1.346 second using v1.01-cache-2.11-cpan-71847e10f99 )