line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package WWW::GoDaddy::REST; |
2
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
137895
|
use warnings; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
118
|
|
4
|
4
|
|
|
4
|
|
14
|
use strict; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
97
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
#<<< NO perltidy - must be all on one line |
7
|
4
|
|
|
4
|
|
1892
|
use version; our $VERSION = version->new('1.00'); |
|
4
|
|
|
|
|
5982
|
|
|
4
|
|
|
|
|
19
|
|
8
|
|
|
|
|
|
|
#>>> |
9
|
4
|
|
|
4
|
|
348
|
use Carp qw(confess); |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
228
|
|
10
|
4
|
|
|
4
|
|
1934
|
use English qw( -no_match_vars ); |
|
4
|
|
|
|
|
9060
|
|
|
4
|
|
|
|
|
27
|
|
11
|
4
|
|
|
4
|
|
2306
|
use File::Slurp qw( slurp ); |
|
4
|
|
|
|
|
20604
|
|
|
4
|
|
|
|
|
273
|
|
12
|
4
|
|
|
4
|
|
2089
|
use LWP::UserAgent; |
|
4
|
|
|
|
|
112803
|
|
|
4
|
|
|
|
|
121
|
|
13
|
4
|
|
|
4
|
|
30
|
use HTTP::Request; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
79
|
|
14
|
4
|
|
|
4
|
|
2478
|
use Moose; |
|
4
|
|
|
|
|
1482700
|
|
|
4
|
|
|
|
|
36
|
|
15
|
4
|
|
|
4
|
|
24880
|
use Moose::Util::TypeConstraints; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
35
|
|
16
|
4
|
|
|
4
|
|
8749
|
use WWW::GoDaddy::REST::Resource; |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
200
|
|
17
|
4
|
|
|
4
|
|
2094
|
use WWW::GoDaddy::REST::Schema; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
153
|
|
18
|
4
|
|
|
4
|
|
22
|
use WWW::GoDaddy::REST::Util qw(abs_url json_encode json_decode is_json ); |
|
4
|
|
|
|
|
5
|
|
|
4
|
|
|
|
|
17
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
subtype 'PositiveInt', as 'Int', where { $_ > 0 }; |
21
|
|
|
|
|
|
|
|
22
|
4
|
|
|
4
|
|
1634
|
no Moose::Util::TypeConstraints; |
|
4
|
|
|
|
|
20
|
|
|
4
|
|
|
|
|
40
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my $JSON_MIME_TYPE = 'application/json'; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
has 'url' => ( |
27
|
|
|
|
|
|
|
is => 'rw', |
28
|
|
|
|
|
|
|
isa => 'Str', |
29
|
|
|
|
|
|
|
required => 1, |
30
|
|
|
|
|
|
|
documentation => 'Base url of the REST service' |
31
|
|
|
|
|
|
|
); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
has 'timeout' => ( |
34
|
|
|
|
|
|
|
is => 'rw', |
35
|
|
|
|
|
|
|
isa => 'PositiveInt', |
36
|
|
|
|
|
|
|
required => 1, |
37
|
|
|
|
|
|
|
default => 10, |
38
|
|
|
|
|
|
|
documentation => 'Timeout in seconds for HTTP calls' |
39
|
|
|
|
|
|
|
); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
has 'basic_username' => ( |
42
|
|
|
|
|
|
|
is => 'rw', |
43
|
|
|
|
|
|
|
isa => 'Str', |
44
|
|
|
|
|
|
|
required => 0, |
45
|
|
|
|
|
|
|
documentation => 'Username portion if using basic auth' |
46
|
|
|
|
|
|
|
); |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
has 'basic_password' => ( |
49
|
|
|
|
|
|
|
is => 'rw', |
50
|
|
|
|
|
|
|
isa => 'Str', |
51
|
|
|
|
|
|
|
required => 0, |
52
|
|
|
|
|
|
|
documentation => 'Password portion if using basic auth' |
53
|
|
|
|
|
|
|
); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
has 'user_agent' => ( |
56
|
|
|
|
|
|
|
is => 'rw', |
57
|
|
|
|
|
|
|
isa => 'Object', |
58
|
|
|
|
|
|
|
required => 1, |
59
|
|
|
|
|
|
|
default => \&default_user_agent, |
60
|
|
|
|
|
|
|
); |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
has 'schemas_file' => ( |
63
|
|
|
|
|
|
|
is => 'rw', |
64
|
|
|
|
|
|
|
isa => 'Str', |
65
|
|
|
|
|
|
|
required => 0, |
66
|
|
|
|
|
|
|
documentation => 'Optional, cached copy of the schemas JSON to avoid HTTP round trip' |
67
|
|
|
|
|
|
|
); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
has 'schemas' => ( |
70
|
|
|
|
|
|
|
is => 'rw', |
71
|
|
|
|
|
|
|
isa => 'ArrayRef[WWW::GoDaddy::REST::Schema]', |
72
|
|
|
|
|
|
|
required => 1, |
73
|
|
|
|
|
|
|
lazy => 1, |
74
|
|
|
|
|
|
|
builder => '_build_schemas' |
75
|
|
|
|
|
|
|
); |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
has 'raise_http_errors' => ( |
78
|
|
|
|
|
|
|
is => 'rw', |
79
|
|
|
|
|
|
|
isa => 'Bool', |
80
|
|
|
|
|
|
|
required => 1, |
81
|
|
|
|
|
|
|
default => 1 |
82
|
|
|
|
|
|
|
); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub BUILD { |
85
|
14
|
|
|
14
|
0
|
15795
|
my ( $self, $params ) = @_; |
86
|
|
|
|
|
|
|
|
87
|
14
|
100
|
100
|
|
|
99
|
if ( defined $params->{basic_username} or defined $params->{basic_password} ) { |
88
|
3
|
100
|
|
|
|
8
|
if ( !defined $params->{basic_username} ) { |
89
|
1
|
|
|
|
|
15
|
confess 'Attribute (basic_username) is required if basic_password is provided'; |
90
|
|
|
|
|
|
|
} |
91
|
2
|
100
|
|
|
|
8
|
if ( !defined $params->{basic_password} ) { |
92
|
1
|
|
|
|
|
36
|
confess 'Attribute (basic_password) is required if basic_username is provided'; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
12
|
100
|
100
|
|
|
172
|
if ( defined $params->{schemas_file} and !-e $params->{schemas_file} ) { |
97
|
1
|
|
|
|
|
27
|
confess 'Attribute (schemas_file) must be a file that exists: ' . $params->{schemas_file}; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub query { |
103
|
8
|
|
|
8
|
1
|
3094
|
my $self = shift; |
104
|
8
|
|
|
|
|
13
|
my $type = shift; |
105
|
8
|
|
|
|
|
22
|
return $self->schema($type)->query(@_); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub query_by_id { |
109
|
15
|
|
|
15
|
1
|
13332
|
my $self = shift; |
110
|
15
|
|
|
|
|
44
|
my $type = shift; |
111
|
15
|
|
|
|
|
72
|
return $self->schema($type)->query_by_id(@_); |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub create { |
115
|
3
|
|
|
3
|
1
|
4928
|
my $self = shift; |
116
|
3
|
|
|
|
|
5
|
my $type = shift; |
117
|
3
|
|
|
|
|
11
|
return $self->schema($type)->create(@_); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub schema { |
121
|
42
|
|
|
42
|
1
|
1534
|
my $self = shift; |
122
|
42
|
|
|
|
|
71
|
my $name = shift; |
123
|
|
|
|
|
|
|
|
124
|
42
|
|
|
|
|
61
|
my @schemas = @{ $self->schemas() }; |
|
42
|
|
|
|
|
1620
|
|
125
|
|
|
|
|
|
|
|
126
|
42
|
|
|
|
|
229
|
return WWW::GoDaddy::REST::Schema->registry_lookup($name); |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
sub schemas_url { |
130
|
100
|
|
|
100
|
1
|
114
|
my $self = shift; |
131
|
100
|
|
100
|
|
|
219
|
my $specific_name = shift || ''; |
132
|
|
|
|
|
|
|
|
133
|
100
|
|
|
|
|
3209
|
my $base = $self->url; |
134
|
100
|
|
|
|
|
320
|
my $path = sprintf( 'schemas/%s', $specific_name ); |
135
|
100
|
|
|
|
|
276
|
return abs_url( $base, $path ); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub http_request_schemas_json { |
139
|
1
|
|
|
1
|
1
|
4
|
my $self = shift; |
140
|
|
|
|
|
|
|
|
141
|
1
|
|
|
|
|
5
|
my $request = $self->build_http_request( 'GET', $self->schemas_url ); |
142
|
1
|
|
|
|
|
26
|
my $response = $self->user_agent->request($request); |
143
|
1
|
|
|
|
|
395
|
my $content = $response->content; |
144
|
1
|
50
|
33
|
|
|
11
|
if ( !$response->is_success && $self->raise_http_errors ) { |
145
|
0
|
|
|
|
|
0
|
die($content); |
146
|
|
|
|
|
|
|
} |
147
|
1
|
|
|
|
|
20
|
return $content; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub http_request_as_resource { |
151
|
35
|
|
|
35
|
1
|
65
|
my ( $self, $method, $url, $content, $http_opts ) = @_; |
152
|
35
|
|
|
|
|
94
|
my ( $struct_from_json, $http_response ) |
153
|
|
|
|
|
|
|
= $self->http_request( $method, $url, $content, $http_opts ); |
154
|
|
|
|
|
|
|
|
155
|
28
|
|
|
|
|
207
|
my $resource = WWW::GoDaddy::REST::Resource->new_subclassed( |
156
|
|
|
|
|
|
|
{ client => $self, |
157
|
|
|
|
|
|
|
fields => $struct_from_json, |
158
|
|
|
|
|
|
|
http_response => $http_response |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
); |
161
|
|
|
|
|
|
|
|
162
|
28
|
50
|
33
|
|
|
33160
|
if ( !$http_response->is_success && $self->raise_http_errors ) { |
163
|
0
|
0
|
|
|
|
0
|
if ($EXCEPTIONS_BEING_CAUGHT) { |
164
|
0
|
|
|
|
|
0
|
die($resource); |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
else { |
167
|
0
|
|
|
|
|
0
|
die( $resource->to_string ); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
28
|
|
|
|
|
425
|
return $resource; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub http_request { |
175
|
35
|
|
|
35
|
1
|
51
|
my $self = shift; |
176
|
35
|
|
|
|
|
52
|
my ( $method, $uri, $perl_data, $http_opts ) = @_; |
177
|
|
|
|
|
|
|
|
178
|
35
|
|
100
|
|
|
105
|
$http_opts ||= {}; |
179
|
35
|
|
66
|
|
|
972
|
$http_opts->{timeout} ||= $self->timeout; |
180
|
|
|
|
|
|
|
|
181
|
35
|
|
|
|
|
1028
|
$uri = abs_url( $self->url, $uri ); |
182
|
|
|
|
|
|
|
|
183
|
35
|
|
|
|
|
2572
|
my $headers = undef; |
184
|
|
|
|
|
|
|
|
185
|
35
|
|
|
|
|
37
|
my $content; |
186
|
35
|
100
|
|
|
|
84
|
if ( defined $perl_data ) { |
187
|
10
|
|
|
|
|
19
|
$content = eval { json_encode($perl_data) }; |
|
10
|
|
|
|
|
58
|
|
188
|
10
|
50
|
|
|
|
38
|
if ($@) { |
189
|
0
|
|
|
|
|
0
|
confess "$@:\n$perl_data"; |
190
|
|
|
|
|
|
|
} |
191
|
10
|
|
|
|
|
33
|
$headers = [ 'Content-type' => $JSON_MIME_TYPE ]; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
35
|
|
|
|
|
115
|
my $request = $self->build_http_request( $method, $uri, $headers, $content ); |
195
|
|
|
|
|
|
|
|
196
|
35
|
|
|
|
|
56
|
my $response = eval { |
197
|
35
|
|
|
6
|
|
416
|
local $SIG{ALRM} = sub { die("alarm\n") }; |
|
6
|
|
|
|
|
5998601
|
|
198
|
35
|
|
|
|
|
152
|
alarm $http_opts->{timeout}; |
199
|
35
|
|
|
|
|
1148
|
return $self->user_agent->request($request); |
200
|
|
|
|
|
|
|
}; |
201
|
35
|
|
|
|
|
4387
|
alarm 0; |
202
|
35
|
100
|
|
|
|
129
|
if ( my $e = $@ ) { |
203
|
7
|
100
|
|
|
|
37
|
if ( $e eq "alarm\n" ) { |
204
|
6
|
|
|
|
|
321
|
confess("timed out while calling '$method' '$uri'"); |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
else { |
207
|
1
|
|
|
|
|
17
|
confess($e); |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
} |
210
|
28
|
|
|
|
|
73
|
my $response_text = $response->content; |
211
|
|
|
|
|
|
|
|
212
|
28
|
|
|
|
|
264
|
my $content_data; |
213
|
28
|
100
|
|
|
|
54
|
if ($response_text) { |
214
|
27
|
|
|
|
|
35
|
$content_data = eval { json_decode($response_text) }; |
|
27
|
|
|
|
|
75
|
|
215
|
27
|
50
|
|
|
|
76
|
if ($@) { |
216
|
0
|
|
|
|
|
0
|
confess "$@:\n$response_text"; |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
else { |
220
|
1
|
|
|
|
|
2
|
$content_data = undef; |
221
|
|
|
|
|
|
|
} |
222
|
28
|
50
|
|
|
|
145
|
return wantarray ? ( $content_data, $response ) : $content_data; |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub build_http_request { |
226
|
36
|
|
|
36
|
1
|
381
|
my $self = shift; |
227
|
36
|
|
|
|
|
83
|
my @params = @_; |
228
|
|
|
|
|
|
|
|
229
|
36
|
|
|
|
|
216
|
my $request = HTTP::Request->new(@params); |
230
|
36
|
50
|
33
|
|
|
4871
|
if ( defined $self->basic_username or defined $self->basic_password ) { |
231
|
0
|
|
|
|
|
0
|
$request->authorization_basic( $self->basic_username, $self->basic_password ); |
232
|
|
|
|
|
|
|
} |
233
|
36
|
|
|
|
|
94
|
return $request; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
sub default_user_agent { |
237
|
10
|
|
|
10
|
1
|
113527
|
my $ua = LWP::UserAgent->new( env_proxy => 1 ); |
238
|
10
|
|
|
|
|
29023
|
$ua->default_headers->push_header( 'Accept' => $JSON_MIME_TYPE ); |
239
|
10
|
|
|
|
|
285
|
return $ua; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
sub _build_schemas { |
243
|
4
|
|
|
4
|
|
8
|
my $self = shift; |
244
|
|
|
|
|
|
|
|
245
|
4
|
|
|
|
|
7
|
my $schema_json; |
246
|
4
|
100
|
|
|
|
128
|
if ( $self->schemas_file ) { |
247
|
3
|
|
|
|
|
73
|
$schema_json = slurp( $self->schemas_file ); |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
else { |
250
|
1
|
|
|
|
|
7
|
$schema_json = $self->http_request_schemas_json; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
4
|
|
|
|
|
376
|
my $struct = eval { json_decode($schema_json) }; |
|
4
|
|
|
|
|
25
|
|
254
|
4
|
50
|
|
|
|
13
|
if ($@) { |
255
|
0
|
|
|
|
|
0
|
confess "$@:\n$schema_json"; |
256
|
|
|
|
|
|
|
} |
257
|
4
|
|
|
|
|
6
|
foreach my $schema_struct ( @{ $struct->{data} } ) { |
|
4
|
|
|
|
|
42
|
|
258
|
44
|
|
|
|
|
177
|
my $schema = WWW::GoDaddy::REST::Resource->new_subclassed( |
259
|
|
|
|
|
|
|
{ client => $self, fields => $schema_struct } ); |
260
|
44
|
|
|
|
|
35180
|
my $key = $schema->link('self'); |
261
|
44
|
|
|
|
|
116
|
WWW::GoDaddy::REST::Schema->registry_add( $schema->id => $schema ); |
262
|
44
|
|
|
|
|
102
|
WWW::GoDaddy::REST::Schema->registry_add( $key => $schema ); |
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
|
265
|
4
|
|
|
|
|
21
|
return [ WWW::GoDaddy::REST::Schema->registry_list ]; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
1; |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head1 NAME |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
WWW::GoDaddy::REST - Work with services conforming to the GDAPI spec |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=head1 SYNOPSIS |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
use WWW::GoDaddy::REST; |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
my $client = WWW::GoDaddy::REST->new({ |
279
|
|
|
|
|
|
|
url => 'https://example.com/v1', |
280
|
|
|
|
|
|
|
basic_username => 'theuser', |
281
|
|
|
|
|
|
|
basic_password => 'notsosecret' |
282
|
|
|
|
|
|
|
}); |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
# see docs for WWW::GoDaddy::REST::Resource for more info |
285
|
|
|
|
|
|
|
my $auto = $client->query_by_id('autos',$vehicle_id_number); |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
print $auto->f('make'); # get a field |
288
|
|
|
|
|
|
|
print $auto->f('model','S'); # set a field |
289
|
|
|
|
|
|
|
$saved_auto = $auto->save(); |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
my $resource = $auto->follow_link('link_name'); |
292
|
|
|
|
|
|
|
my $resource = $auto->do_action('drive', { lat => ..., lon => ...}); |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
my $new = $client->create('autos', { 'make' => 'Tesla', 'model' => 'S' }); |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
$auto->delete(); |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
my @autos = $client->query('autos',{ 'make' => 'tesla' }); |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head1 DESCRIPTION |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
This client makes it easy to code against a REST API that is created using |
303
|
|
|
|
|
|
|
the Go Daddy (r) API Specification (GDAPI) L<https://github.com/godaddy/gdapi>. |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
You will typically only need three pieces of information: |
306
|
|
|
|
|
|
|
- base url of the api (this must include the version number) |
307
|
|
|
|
|
|
|
- username |
308
|
|
|
|
|
|
|
- password |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=head1 SEARCHING AND FILTERS |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
There are two methods that deal with searching: C<query> and C<query_by_id>. |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=head2 SEARCH BY ID |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Example: |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# GET /v1/how_the_schema_defines/the_resource/url/id |
319
|
|
|
|
|
|
|
$resource = $client->query_by_id('the_schema','the_id'); |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# GET /v1/how_the_schema_defines/the_resource/url/id?other=param |
322
|
|
|
|
|
|
|
$resource = $client->query_by_id('the_schema','the_id', { other => 'param' }); |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=head2 SEARCH WITH FILTER |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Filters are hash references. The first level key is the field |
327
|
|
|
|
|
|
|
name that you are searching on. The value of the field is an array |
328
|
|
|
|
|
|
|
reference that has a list of hash references. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Full Syntax Example: |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
@items = $client->query( 'the_schema_name', |
333
|
|
|
|
|
|
|
{ |
334
|
|
|
|
|
|
|
'your_field_name' => [ |
335
|
|
|
|
|
|
|
{ |
336
|
|
|
|
|
|
|
'modifier' => 'your modifier like "eq" or "ne"', |
337
|
|
|
|
|
|
|
'value' => 'your search value' |
338
|
|
|
|
|
|
|
}, |
339
|
|
|
|
|
|
|
{ |
340
|
|
|
|
|
|
|
#... |
341
|
|
|
|
|
|
|
}, |
342
|
|
|
|
|
|
|
], |
343
|
|
|
|
|
|
|
'another_field' => ... |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
); |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Now there are shortcuts as well. |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
Single Field Equality Example: |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
@items = $client->query( 'the_schema_name', |
352
|
|
|
|
|
|
|
{ 'your_field_name' => 'your search value' } |
353
|
|
|
|
|
|
|
); |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
Assumed Equality Example: |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
@items = $client->query( 'the_schema_name', |
358
|
|
|
|
|
|
|
{ |
359
|
|
|
|
|
|
|
'your_field_name' => [ |
360
|
|
|
|
|
|
|
{ |
361
|
|
|
|
|
|
|
# notice the missing 'modifier' key |
362
|
|
|
|
|
|
|
'value' => 'your search value', |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
], |
365
|
|
|
|
|
|
|
'another_field' => 'equality search too' |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
); |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
Pass Through to query_by_id VS Search |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
$resource = $client->query( 'the_schema_name', 'id' ); |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
Attributes can be provided in the C<new> method and have corresponding |
376
|
|
|
|
|
|
|
methods to get/set the values. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=over 4 |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=item url |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
Base URL for the web service. This must include the version portion of the |
383
|
|
|
|
|
|
|
URL as well. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
Trailing slash can be present or left out. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
Example: |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new( { |
390
|
|
|
|
|
|
|
url => 'https://example.com/v1' |
391
|
|
|
|
|
|
|
} ); |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=item basic_username |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
The username or key you were assigned for the web service. |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
Example: |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new( { |
400
|
|
|
|
|
|
|
url => '...', |
401
|
|
|
|
|
|
|
basic_username => 'me', |
402
|
|
|
|
|
|
|
basic_password => '...' |
403
|
|
|
|
|
|
|
} ); |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
NOTE: not all web services authenticate using HTTP Basic Auth. In this case, |
406
|
|
|
|
|
|
|
you will need to provide your own C<user_agent> with default headers to |
407
|
|
|
|
|
|
|
accomplish authentication on your own. |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=item basic_password |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
The password or secret you were assigned for the web service. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
Example: |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new( { |
416
|
|
|
|
|
|
|
url => '...', |
417
|
|
|
|
|
|
|
basic_username => '...', |
418
|
|
|
|
|
|
|
basic_password => 'very_secret' |
419
|
|
|
|
|
|
|
} ); |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
NOTE: not all web services authenticate using HTTP Basic Auth. In this case, |
422
|
|
|
|
|
|
|
you will need to provide your own C<user_agent> with default headers to |
423
|
|
|
|
|
|
|
accomplish authentication on your own. |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=item user_agent |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
The instance of L<LWP::UserAgent> that is used for all HTTP(S) interraction. |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
This has a sane default if you do not provide an instance yourself. |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
You may override this if you wish in the constructor or later on at runtime. |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
See the C<default_user_agent> in L<"CLASS METHODS">. |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
Example: |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
$ua = LWP::UserAgent->new(); |
438
|
|
|
|
|
|
|
$ua->default_headers->push_header( |
439
|
|
|
|
|
|
|
'Authorization' => 'MyCustom ASDFDAFFASFASFSAFSDFAS==' |
440
|
|
|
|
|
|
|
); |
441
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({ |
442
|
|
|
|
|
|
|
url => '...', |
443
|
|
|
|
|
|
|
user_agent => $ua |
444
|
|
|
|
|
|
|
}); |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=item schemas_file |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
Optional path to a file containing the JSON for all of the schemas for this web |
449
|
|
|
|
|
|
|
service (from the schemas collection). If you would like to avoid a round trip |
450
|
|
|
|
|
|
|
to the server at runtime, this is the way to do it. |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
Example: |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({ |
455
|
|
|
|
|
|
|
url => '...', |
456
|
|
|
|
|
|
|
schemas_file => '/my/app/schema.json' |
457
|
|
|
|
|
|
|
}); |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
See the GDAPI Specification for more information about schemas and collections. |
460
|
|
|
|
|
|
|
L<https://github.com/godaddy/gdapi/blob/master/specification.md> |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=item raise_http_errors |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
Boolean value that indicates whether a C<die()> will occur in the |
465
|
|
|
|
|
|
|
event of a non successful HTTP response (4xx 5xx etc). |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
It defaults to True. Set to a false value if you wish to check |
468
|
|
|
|
|
|
|
the HTTP response code in the resultant resource on your own. |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=back |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=head1 METHODS |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=over 4 |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=item query |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
Search for a list of resources given a schema name and a filter. |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
If the second parameter is a scalar, is assumes you are not searching but rather |
481
|
|
|
|
|
|
|
trying to load a specific resource. |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
See the documentation for C<query_by_id>. |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
In scalar context, this returns a L<Collection|WWW::GoDaddy::REST::Collection> |
486
|
|
|
|
|
|
|
object. |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
In list context, this returns a list of L<Resource|WWW::GoDaddy::REST::Resource> |
489
|
|
|
|
|
|
|
objects (or subclasses). |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Example: |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
@items = $client->query('schema_name',{ 'field' => 'value' }); |
495
|
|
|
|
|
|
|
$collection = $client->query('schema_name',{ 'field' => 'value' }); |
496
|
|
|
|
|
|
|
$item = $client->query('schema_name','1234'); |
497
|
|
|
|
|
|
|
$item = $client->query('schema_name','1234',{ 'field' => 'value' }); |
498
|
|
|
|
|
|
|
$item = $client->query('schema_name','1234',undef,{ timeout => 15 }); |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
See L<"SEARCHING AND FILTERS"> for more information. |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=item query_by_id |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
Search for a single instance of a resource by its primary id. Optionally |
505
|
|
|
|
|
|
|
specify a hash for additional query params to append to the resource URL. |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
This returns a L<Resource|WWW::GoDaddy::REST::Resource> (or a subclass). |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
Example: |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
# GET /v1/how_the_schema_defines/the_resource/url/the_id |
512
|
|
|
|
|
|
|
$resource = $client->query_by_id('the_schema','the_id'); |
513
|
|
|
|
|
|
|
$resource = $client->query_by_id('the_schema','the_id',undef,{ timeout => 15 }); |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
# GET /v1/how_the_schema_defines/the_resource/url/the_id?other=param |
516
|
|
|
|
|
|
|
$resource = $client->query_by_id('the_schema','the_id', { other => 'param' }); |
517
|
|
|
|
|
|
|
$resource = $client->query_by_id('the_schema','the_id', { other => 'param' }, { timeout => 15 }); |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=item create |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Given a schema and a resource (or hashref), a POST will be made |
522
|
|
|
|
|
|
|
against the collection url of the schema to create the resource. |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
This returns a L<WWW::GoDaddy::REST::Resource> (or a subclass). |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
Example: |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
$car = $client->create('autos', { 'make' => 'Tesla', 'model' => 'S' }); |
529
|
|
|
|
|
|
|
$car = $client->create('autos', { 'make' => 'Tesla', 'model' => 'S' }, { timeout => 30 }); |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
=item schema |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
Given a schema name, return a L<WWW::GoDaddy::REST::Schema> object or |
534
|
|
|
|
|
|
|
undef if it is not found. |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
Example: |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
$schema_resource = $client->schema('the_schema'); |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=item schemas_url |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
If no schema name is provided, return the schema collection url where you can |
543
|
|
|
|
|
|
|
retrieve the collection of all schemas. |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
If a schema name is provided, return the URL where you can retrieve the schema |
546
|
|
|
|
|
|
|
with the given name. |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Example: |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({url => 'http://example.com/v1/'}); |
551
|
|
|
|
|
|
|
$c->schemas_url(); # http://example.com/v1/schemas/ |
552
|
|
|
|
|
|
|
$c->schemas_url('error'); # http://example.com/v1/schemas/error |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=item http_request |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
Perform the HTTP request and return a hashref of the decoded JSON response. |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
If this is called in list context, it returns the decoded JSON response and |
559
|
|
|
|
|
|
|
the associated L<HTTP::Response> object. |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
This takes the following parameters (similar but not the same as L<HTTP::Request>): |
562
|
|
|
|
|
|
|
- HTTP method |
563
|
|
|
|
|
|
|
- URL relative to the web service base C<url> |
564
|
|
|
|
|
|
|
- Optional hashref of data to send as JSON content |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
The url provided will be rooted to the base url, C<url>. |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
Example: |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({ |
571
|
|
|
|
|
|
|
url => 'http://example.com/v1/' |
572
|
|
|
|
|
|
|
}); |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
# GET http://example.com/v1/servers/Asdf |
575
|
|
|
|
|
|
|
$data_hashref = $c->http_request('GET','/servers/Asdf') |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
($hash,$http_response) = $c->http_request('GET','/servers/Asdf'); |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=item http_request_as_resource |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
Perform the HTTP request and return a L<WWW::GoDaddy::REST::Resource> instance. |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
This takes the following parameters (similar but not the same as L<HTTP::Request>): |
584
|
|
|
|
|
|
|
- HTTP method |
585
|
|
|
|
|
|
|
- URL relative to the web service base C<url> |
586
|
|
|
|
|
|
|
- Optional hashref of data to send as JSON content |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
The url provided will be rooted to the base url, C<url>. |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
The url provided will be rooted to the base url, C<url>. |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
Example: |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({ |
595
|
|
|
|
|
|
|
url => 'http://example.com/v1/' |
596
|
|
|
|
|
|
|
}); |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
# GET http://example.com/v1/servers/Asdf |
599
|
|
|
|
|
|
|
$resource = $c->http_request_as_resource('GET','/servers/Asdf') |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=item http_request_schemas_json |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
Retrieve the JSON string for the schemas collection. |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
Example: |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({ |
608
|
|
|
|
|
|
|
url => 'http://example.com/v1/' |
609
|
|
|
|
|
|
|
}); |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
$schemas_json = $c->http_request_schemas_json(); |
612
|
|
|
|
|
|
|
# write this out to a file for later use |
613
|
|
|
|
|
|
|
# with the 'schemas_file' parameter for example |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
=item build_http_request |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
Given parameters for a L<HTTP::Request> object, return an instance |
619
|
|
|
|
|
|
|
of this object with certain defaults filled in. |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
As of this writing the defaults filled in are: |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
- HTTP basic auth headers if auth is provided |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
Unlike other methods such as C<http_request>, the C<url> is not rooted |
626
|
|
|
|
|
|
|
to the base url. |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
Example: |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({ |
632
|
|
|
|
|
|
|
url => 'http://example.com/v1/' |
633
|
|
|
|
|
|
|
}); |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
$request = $c->build_http_request('GET','http://example.com/v1/test'); |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
=back |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
=head1 CLASS METHODS |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
=over 4 |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
=item default_user_agent |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
Generate a default L<LWP::UserAgent>. See C<user_agent>. |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
Example: |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
$ua = WWW::GoDaddy::REST->default_user_agent(); |
650
|
|
|
|
|
|
|
$ua->default_headers->push('X-Custom' => 'thing'); |
651
|
|
|
|
|
|
|
$c = WWW::GoDaddy::REST->new({ |
652
|
|
|
|
|
|
|
user_agent => $ua, |
653
|
|
|
|
|
|
|
url => '...' |
654
|
|
|
|
|
|
|
}); |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=back |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
=head1 SEE ALSO |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
C<gdapi-shell> command line program. |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
=head1 AUTHOR |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
David Bartle, C<< <davidb@mediatemple.net> >> |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
Copyright (c) 2014 Go Daddy Operating Company, LLC |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a |
671
|
|
|
|
|
|
|
copy of this software and associated documentation files (the "Software"), |
672
|
|
|
|
|
|
|
to deal in the Software without restriction, including without limitation |
673
|
|
|
|
|
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
674
|
|
|
|
|
|
|
and/or sell copies of the Software, and to permit persons to whom the |
675
|
|
|
|
|
|
|
Software is furnished to do so, subject to the following conditions: |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in |
678
|
|
|
|
|
|
|
all copies or substantial portions of the Software. |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
681
|
|
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
682
|
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
683
|
|
|
|
|
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
684
|
|
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
685
|
|
|
|
|
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
686
|
|
|
|
|
|
|
DEALINGS IN THE SOFTWARE. |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
=cut |