File Coverage

blib/lib/Search/Typesense/Role/Request.pm
Criterion Covered Total %
statement 31 42 73.8
branch 3 12 25.0
condition 3 6 50.0
subroutine 7 10 70.0
pod n/a
total 44 70 62.8


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