File Coverage

blib/lib/API/Client.pm
Criterion Covered Total %
statement 15 79 18.9
branch 0 16 0.0
condition 0 20 0.0
subroutine 5 14 35.7
pod 5 8 62.5
total 25 137 18.2


line stmt bran cond sub pod time code
1             # ABSTRACT: General-Purpose API Client Abstraction
2             package API::Client;
3              
4 1     1   1442 use Data::Object::Class;
  1         20329  
  1         9  
5 1     1   2367 use Data::Object::Signatures;
  1         4597644  
  1         11  
6              
7 1         5 use Data::Object::Library qw(
8             InstanceOf
9             Int
10             Str
11 1     1   9243 );
  1         2  
12              
13             extends 'API::Client::Core';
14              
15 1     1   975 use Carp ();
  1         2  
  1         17  
16 1     1   5 use Scalar::Util ();
  1         2  
  1         627  
17              
18             our $VERSION = '0.03'; # VERSION
19              
20             # ATTRIBUTES
21              
22             has casing => (
23             is => 'rw',
24             isa => Str,
25             default => 'lowercase',
26             required => 0,
27             );
28              
29             has credentials => (
30             is => 'ro',
31             isa => InstanceOf['API::Client::Credentials'],
32             required => 0,
33             );
34              
35             has identifier => (
36             is => 'rw',
37             isa => Str,
38             default => 'API::Client (Perl)',
39             required => 0,
40             );
41              
42             has version => (
43             is => 'rw',
44             isa => Str,
45             default => 0,
46             required => 0,
47             );
48              
49             # METHOD-RESOLUTION
50              
51 0     0     method AUTOLOAD () {
  0            
52              
53 0           my @words = split /::/, our $AUTOLOAD;
54              
55 0           my $method = pop @words;
56 0           my $package = join '::', @words;
57              
58 0 0 0       Carp::croak("Undefined subroutine &${package}::$method called")
59             unless Scalar::Util::blessed($self) && $self->isa(__PACKAGE__);
60              
61 0           my @segments = @_;
62 0           my @results = ();
63              
64             # attempt to automate path casing
65 0           while (my ($path, $param) = splice @segments, 0, 2) {
66 0           my $casing = $self->casing;
67              
68 0 0 0       if (defined $param and $casing eq 'lowercase') {
    0 0        
    0 0        
    0 0        
    0 0        
69 0           $path = lc $path;
70             }
71             elsif (defined $param and $casing eq 'snakecase') {
72 0           my ($first, @remaining) = split /_/, $path;
73 0           $path = join '', $first, map ucfirst, @remaining;
74             }
75             elsif (defined $param and $casing eq 'camelcase') {
76 0           my ($first, @remaining) = split /_/, $path;
77 0           $path = join '', $first, map ucfirst, @remaining;
78             }
79             elsif (defined $param and $casing eq 'pascalcase') {
80 0           $path = join '', map ucfirst, split /_/, $path;
81             }
82             elsif (defined $param and $casing eq 'uppercase') {
83 0           $path = uc $path;
84             }
85              
86 0 0         push @results, $path, defined $param ? $param : ();
87             }
88              
89             # return new resource instance dynamically
90 0           return $self->resource($method, @results);
91              
92             }
93              
94             # CONSTRUCTION
95              
96 0     0 0   method BUILD () {
  0            
97              
98 0           my $ident = $self->identifier;
99 0           my $agent = $self->user_agent;
100              
101             # identify the API client
102 0           $agent->transactor->name($ident);
103              
104 0           return $self;
105              
106             }
107              
108             # METHODS
109              
110 0     0 0   method PREPARE ($ua, $tx, %args) {
  0            
  0            
111              
112 0 0         if (my $credentials = $self->credentials) {
113              
114             # process credentials
115 0           $credentials->process($tx);
116              
117             }
118              
119 0           my $headers = $tx->req->headers;
120 0           my $url = $tx->req->url;
121              
122             # default headers
123 0           $headers->header('Content-Type' => 'application/json');
124              
125 0           return $self;
126              
127             }
128              
129 0     0 1   method action ($method, %args) {
  0            
  0            
130              
131 0   0       $method = uc($method || 'get');
132              
133             # execute transaction and return response
134 0           return $self->$method(%args);
135              
136             }
137              
138 0     0 1   method create (%args) {
  0            
  0            
139              
140             # execute transaction and return response
141 0           return $self->POST(%args);
142              
143             }
144              
145 0     0 1   method delete (%args) {
  0            
  0            
146              
147             # execute transaction and return response
148 0           return $self->DELETE(%args);
149              
150             }
151              
152 0     0 1   method fetch (%args) {
  0            
  0            
153              
154             # execute transaction and return response
155 0           return $self->GET(%args);
156              
157             }
158              
159 0     0 0   method resource (@segments) {
  0            
  0            
160              
161 0           my $class = ref($self);
162              
163             # build new resource instance
164 0           my $instance = $class->new(
165             debug => $self->debug,
166             fatal => $self->fatal,
167             retries => $self->retries,
168             timeout => $self->timeout,
169             user_agent => $self->user_agent,
170             identifier => $self->identifier,
171             version => $self->version,
172             # attempt to deduce other attributes
173             %$self
174             );
175              
176             # resource locator
177 0           my $url = $instance->url;
178              
179             # modify resource locator if possible
180 0           $url->path(join '/', $self->url->path, @segments);
181              
182             # return resource instance
183 0           return $instance;
184              
185             }
186              
187 0     0 1   method update (%args) {
  0            
  0            
188              
189             # execute transaction and return response
190 0           return $self->PUT(%args);
191              
192             }
193              
194             1;
195              
196             __END__