File Coverage

lib/Wing/Client.pm
Criterion Covered Total %
statement 49 50 98.0
branch 6 8 75.0
condition 4 8 50.0
subroutine 14 14 100.0
pod n/a
total 73 80 91.2


line stmt bran cond sub pod time code
1 2     2   807 use strict;
  2         4  
  2         53  
2 2     2   9 use warnings;
  2         4  
  2         81  
3             package Wing::Client;
4             $Wing::Client::VERSION = '1.1000';
5 2     2   11 use HTTP::Thin;
  2         4  
  2         47  
6 2     2   919 use HTTP::Request::Common;
  2         6176  
  2         126  
7 2     2   730 use HTTP::CookieJar;
  2         54903  
  2         120  
8 2     2   27 use JSON;
  2         6  
  2         21  
9 2     2   353 use URI;
  2         5  
  2         55  
10 2     2   13 use Ouch;
  2         4  
  2         47  
11 2     2   1444 use Moo;
  2         20369  
  2         11  
12              
13              
14             =head1 NAME
15              
16             Wing::Client - A simple client to Wing's web services.
17              
18             =head1 VERSION
19              
20             version 1.1000
21              
22             =head1 SYNOPSIS
23              
24             use Wing::Client;
25              
26             my $wing = Wing::Client->new(uri => 'https://www.thegamecrafter.com');
27              
28             my $game = $wing->get('game/528F18A2-F2C4-11E1-991D-40A48889CD00');
29            
30             my $session = $wing->post('session', { username => 'me', password => '123qwe', api_key_id => 'abcdefghijklmnopqrztuz' });
31              
32             $game = $wing->put('game/528F18A2-F2C4-11E1-991D-40A48889CD00', { session_id => $session->{id}, name => 'Lacuna Expanse' });
33              
34             my $status = $wing->delete('game/528F18A2-F2C4-11E1-991D-40A48889CD00', { session_id => $session->{id} });
35              
36             =head1 DESCRIPTION
37              
38             A light-weight wrapper for Wing's (L) RESTful API (an example of which can be found at: L). This wrapper basically hides the request cycle from you so that you can get down to the business of using the API. It doesn't attempt to manage the data structures or objects the web service interfaces with.
39              
40             =head1 METHODS
41              
42             The following methods are available.
43              
44             =head2 new ( params )
45              
46             Constructor.
47              
48             =over
49              
50             =item params
51              
52             A hash of parameters.
53              
54             =over
55              
56             =item uri
57              
58             The base URI of the service you're interacting with. Example: C.
59              
60             =item session_id
61              
62             A Wing session_id. If set, this is automatically added to all requests because I'm lazy. If you don't
63             want a session_id for a while, set the C flag on the object.
64              
65             =item no_session_id
66              
67             If set to true, prevents adding the session_id to the request.
68              
69             =cut
70              
71             has uri => (
72             is => 'rw',
73             required => 1,
74             );
75              
76             =item agent
77              
78             A LWP::UserAgent object used to keep a persistent cookie_jar across requests.
79              
80             =back
81              
82             =back
83              
84             =cut
85              
86             has agent => (
87             is => 'ro',
88             required => 0,
89             lazy => 1,
90             builder => '_build_agent',
91             );
92              
93             sub _build_agent {
94 2     2   77 return HTTP::Thin->new( cookie_jar => HTTP::CookieJar->new() )
95             }
96              
97             has [qw/session_id no_session_id/] => (
98             is => 'rw',
99             required => 0,
100             );
101              
102             ##Optionally add a session id, if the following conditions are met:
103             ## 1) A session_id was put into the object
104             ## 2) no_session_id was not set
105             ## 3) No session_id was passed with any parameters when calling the method.
106              
107             sub _add_session_id {
108 7     7   621822 my $orig = shift;
109 7         22 my $self = shift;
110 7         21 my $uri = shift;
111 7   100     54 my $params = shift || {};
112 7 0 33     76 if ($self->session_id && ! $self->no_session_id && ! exists $params->{session_id}) {
      33        
113 0         0 $params->{session_id} = $self->session_id;
114             }
115 7         38 return $self->$orig($uri, $params, @_);
116             }
117              
118             around get => \&_add_session_id;
119             around post => \&_add_session_id;
120             around put => \&_add_session_id;
121             around delete => \&_add_session_id;
122              
123             =head2 get(path, params)
124              
125             Performs a C request, which is used for reading data from the service.
126              
127             =over
128              
129             =item path
130              
131             The path to the REST interface you wish to call. You can abbreviate and leave off the C part if you wish.
132              
133             =item params
134              
135             A hash reference of parameters you wish to pass to the web service.
136              
137             =back
138              
139             =cut
140              
141             sub get {
142             my ($self, $path, $params) = @_;
143             my $uri = $self->_create_uri($path);
144             $uri->query_form($params);
145             return $self->_process_request( GET $uri );
146             }
147              
148             =head2 delete(path, params)
149              
150             Performs a C request, deleting data from the service.
151              
152             =over
153              
154             =item path
155              
156             The path to the REST interface you wish to call. You can abbreviate and leave off the C part if you wish.
157              
158             =item params
159              
160             A hash reference of parameters you wish to pass to the web service.
161              
162             =back
163              
164             =cut
165              
166             sub delete {
167             my ($self, $path, $params) = @_;
168             my $uri = $self->_create_uri($path);
169             return $self->_process_request(POST $uri->as_string, $params, 'X-HTTP-Method' => 'DELETE', Content_Type => 'form-data', Content => $params );
170             }
171              
172             =head2 put(path, params, options)
173              
174             Performs a C request, which is used for updating data in the service.
175              
176             =over
177              
178             =item path
179              
180             The path to the REST interface you wish to call. You can abbreviate and leave off the C part if you wish.
181              
182             =item params
183              
184             A hash reference of parameters you wish to pass to the web service.
185              
186             =item options
187              
188             =over
189              
190             =item upload
191              
192             Defaults to 0. If 1 then when you pass a param that is an array reference, the value of that array reference will be assumed to be a file name and will attempt to be uploaded per the inner workings of L.
193              
194             =back
195              
196             =back
197              
198             =cut
199              
200             sub put {
201             my ($self, $path, $params, $options) = @_;
202             my $uri = $self->_create_uri($path);
203             my %headers = ( 'X-HTTP-Method' => 'PUT',Content => $params );
204             if ($options->{upload}) {
205             $headers{Content_Type} = 'form-data';
206             }
207             return $self->_process_request( POST $uri->as_string, %headers);
208             }
209              
210             =head2 post(path, params, options)
211              
212             Performs a C request, which is used for creating data in the service.
213              
214             =over
215              
216             =item path
217              
218             The path to the REST interface you wish to call. You can abbreviate and leave off the C part if you wish.
219              
220             =item params
221              
222             A hash reference of parameters you wish to pass to the web service.
223              
224             =item options
225              
226             =over
227              
228             =item upload
229              
230             Defaults to 0. If 1 then when you pass a param that is an array reference, the value of that array reference will be assumed to be a file name and will attempt to be uploaded per the inner workings of L.
231              
232             =back
233              
234             =back
235              
236             =cut
237              
238             sub post {
239             my ($self, $path, $params, $options) = @_;
240             my $uri = $self->_create_uri($path);
241             my %headers = ( Content => $params );
242             if ($options->{upload}) {
243             $headers{Content_Type} = 'form-data';
244             }
245             return $self->_process_request( POST $uri->as_string, %headers );
246             }
247              
248             sub _create_uri {
249 7     7   99 my $self = shift;
250 7         20 my $path = shift;
251 7 100       37 unless ($path =~ m/^\/api/) {
252 6         26 $path = '/api/'.$path;
253             }
254 7         95 return URI->new($self->uri.$path);
255             }
256              
257             sub _process_request {
258 7     7   28960 my $self = shift;
259 7         273 $self->_process_response($self->agent->request( @_ ));
260             }
261              
262             sub _process_response {
263 9     9   2167269 my $self = shift;
264 9         26 my $response = shift;
265 9         26 my $result = eval { from_json($response->decoded_content) };
  9         71  
266 9 100       3421 if ($@) {
    100          
267 1         8 ouch 500, 'Server returned unparsable content.', { error => $@, content => $response->decoded_content };
268             }
269             elsif ($response->is_success) {
270 7         291 return $result->{result};
271             }
272             else {
273 1         28 ouch $result->{error}{code}, $result->{error}{message}, $result->{error}{data};
274             }
275             }
276              
277             =head1 PREREQS
278              
279             L
280             L
281             L
282             L
283             L
284             L
285             L
286              
287             =head1 SUPPORT
288              
289             =over
290              
291             =item Repository
292              
293             L
294              
295             =item Bug Reports
296              
297             L
298              
299             =back
300              
301             =head1 AUTHOR
302              
303             JT Smith
304              
305             =head1 LEGAL
306              
307             This module is Copyright 2013 Plain Black Corporation. It is distributed under the same terms as Perl itself.
308              
309             =cut
310              
311             1;