File Coverage

blib/lib/Search/Typesense/Role/Request.pm
Criterion Covered Total %
statement 30 41 73.1
branch 4 14 28.5
condition 3 6 50.0
subroutine 6 9 66.6
pod n/a
total 43 70 61.4


line stmt bran cond sub pod time code
1             package Search::Typesense::Role::Request;
2              
3 4     4   19583 use v5.16.0;
  4         18  
4 4     4   31 use Moo::Role;
  4         11  
  4         27  
5 4         42 use Search::Typesense::Types qw(
6             Enum
7             compile
8 4     4   2662 );
  4         11  
9              
10             our $VERSION = '0.06';
11              
12             requires qw(
13             _ua
14             _url_base
15             );
16              
17             sub _url {
18 3     3   10 my ( $self, $path ) = @_;
19 3         90 return $self->_url_base->clone->path( '/' . join( '/' => @$path ) );
20             }
21              
22             sub _GET {
23 3     3   17 my ( $self, %arg_for ) = @_;
24 3         8 my $request = $arg_for{request};
25 3 50       15 my @args = $request ? ( form => $request ) : ();
26 3         16 return $self->_handle_request( \%arg_for, \@args );
27             }
28              
29             sub _DELETE {
30 0     0   0 my ( $self, %arg_for ) = @_;
31 0         0 return $self->_handle_request( \%arg_for );
32             }
33              
34             sub _POST {
35 0     0   0 my ( $self, %arg_for ) = @_;
36 0         0 my $request = $arg_for{request};
37 0 0       0 my @args = ref $request ? ( json => $request ) : $request;
38 0         0 return $self->_handle_request( \%arg_for, \@args );
39             }
40              
41             sub _PATCH {
42 0     0   0 my ( $self, %arg_for ) = @_;
43 0         0 my $request = $arg_for{request};
44 0 0       0 my @args = ref $request ? ( json => $request ) : $request;
45 0         0 return $self->_handle_request( \%arg_for, \@args );
46             }
47              
48             sub _handle_request {
49 3     3   11 my ( $self, $arg_for, $args ) = @_;
50              
51             # We must only be called by methods like _GET, _POST, _DELETE, and so on.
52             # We strip the package name and leading underscore
53             # (Search::Typesense::_GET becomes GET) and then we call lc() on what's
54             # left. That becomes our HTTP verb and the $check verifies that this is an
55             # allowed verb.
56 3         18 my ( undef, undef, undef, $method ) = caller(1);
57 3         92 $method =~ s/^.*::_//;
58 3         29 state $check = compile( Enum [qw/get delete post patch/] );
59 3         70417 ($method) = $check->( lc $method );
60              
61             # make the actual request, passing a query string, if any, and passing any
62             # args, if any (those can become part of a query string for GET, or part
63             # of the body for other HTTP verbs
64 3 50       51 my @args = $args ? @$args : ();
65 3   50     22 my $url = $self->_url( $arg_for->{path} )->query( $arg_for->{query} || {} );
66 3         1069 my $tx = $self->_ua->$method( $url, @args );
67 3         12642 my $res = $tx->res;
68              
69             # If the response is not succesful, return nothing if it's a 404.
70             # Otherwise, croak()
71 3 50       30 unless ( $res->is_success ) {
72 3 50 50     135 return if ( $res->code // 0 ) == 404;
73 3   50     41 my $message = $res->message // '';
74              
75 3         48 my $body = $res->body;
76 3         260 my $method = $tx->req->method;
77 3         33 my $url = $tx->req->url;
78 3         37 croak("'$method $url' failed: $message. $body");
79             }
80              
81 0 0         return $arg_for->{return_transaction} ? $tx : $tx->res->json;
82             } ## end sub _check_for_failure
83              
84             1;
85              
86             __END__
87              
88             =head1 NAME
89              
90             Search::Typesense::Role::Request - No user-serviceable parts inside.