PONAPI-Server/lib/PONAPI/DAO/Request.pm
# ABSTRACT: DAO request class
package PONAPI::DAO::Request;
use Moose;
use JSON::MaybeXS;
use PONAPI::Document;
has repository => (
is => 'ro',
does => 'PONAPI::Repository',
required => 1,
);
has document => (
is => 'ro',
isa => 'PONAPI::Document',
required => 1,
);
has type => (
is => 'ro',
isa => 'Str',
required => 1,
);
has send_doc_self_link => (
is => 'ro',
isa => 'Bool',
default => sub { 0 },
);
has is_valid => (
is => 'ro',
isa => 'Bool',
default => sub { 1 },
writer => '_set_is_valid',
);
has json => (
is => 'ro',
isa => JSON::MaybeXS::JSON(),
default => sub { JSON::MaybeXS->new->allow_nonref->utf8->canonical },
);
sub BUILDARGS {
my $class = shift;
my %args = @_ == 1 ? %{ $_[0] } : @_;
die "[__PACKAGE__] missing arg `version`"
unless defined $args{version};
$args{document} = PONAPI::Document->new(
version => $args{version},
req_path => $args{req_path} // '/',
req_base => $args{req_base} // '/',
);
return \%args;
}
# These validation methods will be overwritten in the appropriate roles.
# They cover the case where an attribute is NOT expected.
sub _validate_id {
my ( $self, $args ) = @_;
return unless defined $args->{id};
$self->_bad_request( "`id` is not allowed for this request" )
}
sub _validate_rel_type {
my ( $self, $args ) = @_;
return unless defined $args->{rel_type};
$self->_bad_request( "`relationship type` is not allowed for this request" );
}
sub _validate_include {
my ( $self, $args ) = @_;
return unless defined $args->{include};
$self->_bad_request( "`include` is not allowed for this request" );
}
sub _validate_fields {
my ( $self, $args ) = @_;
return unless defined $args->{fields};
$self->_bad_request( "`fields` is not allowed for this request" );
}
sub _validate_filter {
my ( $self, $args ) = @_;
return unless defined $args->{filter};
$self->_bad_request( "`filter` is not allowed for this request" );
}
sub _validate_sort {
my ( $self, $args ) = @_;
return unless defined $args->{sort};
$self->_bad_request( "`sort` is not allowed for this request" );
}
sub _validate_page {
my ( $self, $args ) = @_;
return unless defined $args->{page};
$self->_bad_request( "`page` is not allowed for this request" );
}
sub BUILD {
my ( $self, $args ) = @_;
# `type` exists
my $type = $self->type;
return $self->_bad_request( "Type `$type` doesn't exist.", 404 )
unless $self->repository->has_type( $type );
$self->_validate_id($args);
$self->_validate_rel_type($args);
$self->_validate_include($args);
$self->_validate_fields($args);
$self->_validate_filter($args);
$self->_validate_sort($args);
$self->_validate_page($args);
# validate `data`
if ( exists $args->{data} ) {
if ( $self->can('data') ) {
$self->_validate_data;
}
else {
$self->_bad_request( "request body is not allowed" );
}
}
elsif ( $self->can('has_data') ) {
$self->_bad_request( "request body is missing `data`" );
}
}
sub response {
my ( $self, @headers ) = @_;
my $doc = $self->document;
$doc->add_self_link
if $self->send_doc_self_link && !$doc->has_link('self');
return (
$doc->status,
\@headers,
(
$doc->status != 204
? $doc->build
: ()
),
);
}
sub _bad_request {
my ( $self, $detail, $status ) = @_;
$self->document->raise_error( $status||400, { detail => $detail } );
$self->_set_is_valid(0);
return;
}
__PACKAGE__->meta->make_immutable;
no Moose; 1;
__END__
=pod
=encoding UTF-8
=head1 NAME
PONAPI::DAO::Request - DAO request class
=head1 VERSION
version 0.003003
=head1 AUTHORS
=over 4
=item *
Mickey Nasriachi <mickey@cpan.org>
=item *
Stevan Little <stevan@cpan.org>
=item *
Brian Fraser <hugmeir@cpan.org>
=back
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2019 by Mickey Nasriachi, Stevan Little, Brian Fraser.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut