File Coverage

blib/lib/API/Client.pm
Criterion Covered Total %
statement 21 83 25.3
branch 0 14 0.0
condition 0 20 0.0
subroutine 7 16 43.7
pod 5 8 62.5
total 33 141 23.4


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