File Coverage

blib/lib/WebAPI/DBIC/Resource/Role/ItemInvoke.pm
Criterion Covered Total %
statement 6 27 22.2
branch 0 16 0.0
condition 0 6 0.0
subroutine 2 4 50.0
pod 0 2 0.0
total 8 55 14.5


line stmt bran cond sub pod time code
1             package WebAPI::DBIC::Resource::Role::ItemInvoke;
2             $WebAPI::DBIC::Resource::Role::ItemInvoke::VERSION = '0.003002';
3              
4 2     2   16471087 use Scalar::Util qw(blessed);
  2         19  
  2         554  
5              
6 2     2   1458 use Moo::Role;
  2         44302  
  2         11  
7              
8              
9             requires 'decode_json';
10             requires 'encode_json';
11             requires 'render_item_as_plain_hash';
12             requires 'throwable';
13             requires 'item';
14              
15             has method => (
16             is => 'ro',
17             required => 1,
18             );
19              
20 0     0 0   sub post_is_create { return 0 }
21              
22             around 'allowed_methods' => sub {
23             return [ qw(POST) ];
24             };
25              
26              
27             sub process_post {
28 0     0 0   my $self = shift;
29              
30             # Here's we're calling a method on the item as a simple generic behaviour.
31             # This is very limited because, for example, the method has no knowledge
32             # that it's being called inside a web service, thus no way to do redirects
33             # or provide HTTP specific rich-exceptions.
34             # If anything more sophisticated is required then it should be implemented
35             # as a specific resource class for the method (or perhaps a role if there's
36             # a set of methods that require similar behaviour).
37              
38             # The POST body content provides a data structure containing the method arguments
39             # { args => [ (@_) ] }
40 0 0         $self->throwable->throw_bad_request(415, errors => "Request content-type not application/json")
41             unless $self->request->header('Content-Type') =~ 'application/.*?json';
42 0           my $invoke_body_data = $self->decode_json($self->request->content);
43 0 0         $self->throwable->throw_bad_request(400, errors => "Request content not a JSON hash")
44             unless ref $invoke_body_data eq 'HASH';
45              
46 0           my @method_args;
47 0 0         if (my $args = delete $invoke_body_data->{args}) {
48 0 0         $self->throwable->throw_bad_request(400, errors => "The args must be an array")
49             if ref $args ne 'ARRAY';
50 0           @method_args = @$args;
51             }
52 0 0         $self->throwable->throw_bad_request(400, errors => "Unknown attributes: @{[ keys %$invoke_body_data ]}")
  0            
53             if keys %$invoke_body_data;
54              
55 0           my $method_name = $self->method;
56             # the method is expected to throw an exception on error.
57 0           my $result_raw = $self->item->$method_name(@method_args);
58              
59 0           my $result_rendered;
60             # return a DBIC resultset as array of hashes of ALL records (no paging)
61 0 0 0       if (blessed($result_raw) && $result_raw->isa('DBIx::Class::ResultSet')) {
    0 0        
62 0           $result_rendered = [ map { $self->render_item_as_plain_hash($_) } $result_raw->all ];
  0            
63             }
64             # return a DBIC result row as a hash
65             elsif (blessed($result_raw) && $result_raw->isa('DBIx::Class::Row')) {
66 0           $result_rendered = $self->render_item_as_plain_hash($result_raw);
67             }
68             # return anything else as raw JSON wrapped in a hash
69             else {
70             # we shouldn't get an object here, but if we do then we
71             # stringify it here to avoid exposing the guts
72 0 0         $result_rendered = { result => (blessed $result_raw) ? "$result_raw" : $result_raw };
73             }
74              
75 0           $self->response->body( $self->encode_json($result_rendered) );
76 0           return 200;
77             }
78              
79             1;
80              
81             __END__
82              
83             =pod
84              
85             =encoding UTF-8
86              
87             =head1 NAME
88              
89             WebAPI::DBIC::Resource::Role::ItemInvoke
90              
91             =head1 VERSION
92              
93             version 0.003002
94              
95             =head1 NAME
96              
97             WebAPI::DBIC::Resource::Role::ItemInvoke - methods for resources representing method calls on item resources
98              
99             =head1 AUTHOR
100              
101             Tim Bunce <Tim.Bunce@pobox.com>
102              
103             =head1 COPYRIGHT AND LICENSE
104              
105             This software is copyright (c) 2015 by Tim Bunce.
106              
107             This is free software; you can redistribute it and/or modify it under
108             the same terms as the Perl 5 programming language system itself.
109              
110             =cut