File Coverage

blib/lib/Yandex/OAuth/Client.pm
Criterion Covered Total %
statement 54 70 77.1
branch 11 12 91.6
condition 1 3 33.3
subroutine 11 16 68.7
pod 4 8 50.0
total 81 109 74.3


line stmt bran cond sub pod time code
1             =encoding utf-8
2              
3             =head1 NAME
4              
5             Yandex::OAuth::Client - base class for any Yandex.API modules
6              
7             =head1 SYNOPSIS
8              
9             use Yandex::OAuth::Client;
10              
11             my $client = Yandex::OAuth::Client->new(token => '************', endpoint => 'https://api-metrika.yandex.ru/');
12              
13             my $client->get(['stat','user_vars'], {
14             pretty => 1,
15             # other params specified for resource
16             });
17             # url converting to https://api-metrika.yandex.ru/stat/user_vars/?pretty=1
18              
19             =head1 DESCRIPTION
20              
21             Yandex::OAuth::Client is base class for any Yandex.API modules
22             Contains get, post, put, delete methods for queries to any APIs Yandex.
23              
24             Looking for contributors for this and other Yandex.APIs
25              
26             =cut
27              
28             package Yandex::OAuth::Client;
29 2     2   2226 use 5.008001;
  2         9  
30 2     2   1060 use utf8;
  2         14  
  2         13  
31 2     2   854 use Modern::Perl;
  2         16201  
  2         21  
32 2     2   1891 use Data::Dumper;
  2         6456  
  2         126  
33              
34 2     2   1321 use LWP::UserAgent;
  2         26169  
  2         62  
35 2     2   14 use Storable qw/ dclone /;
  2         5  
  2         202  
36 2     2   12 use JSON::XS;
  2         5  
  2         110  
37 2     2   838 use Moo;
  2         13834  
  2         13  
38              
39             has 'ua' => (
40             is => 'ro',
41             default => sub {
42             my $ua = LWP::UserAgent->new();
43             $ua->agent( 'Yandex::OAuth Perl API Client' );
44             $ua->timeout( 120 );
45             return $ua;
46             }
47             );
48              
49             has 'token' => (
50             is => 'rw',
51             required => 1,
52             );
53              
54             has 'endpoint' => (
55             is => 'rw',
56             required => 1,
57             );
58              
59             has 'next_url' => (
60             is => 'rw',
61             default => '',
62             writer => 'set_next_url',
63             );
64              
65             has 'demo' => (
66             is => 'rw'
67             );
68              
69             =head1 CONSTRUCTOR
70              
71             =over
72              
73             =item B
74              
75             Require two arguments: token and endpoint. For module based on Yandex::OAuth::Client
76             you can override atribute 'endpoint'
77            
78             extends 'Yandex::OAuth::Client';
79             has '+endpoint' => (
80             is => 'ro',
81             default => 'https://api-metrika.yandex.ru/',
82             );
83              
84             =back
85              
86             =head1 METHODS
87              
88             =over
89              
90             =item B
91              
92             Send GET request.
93              
94             $client->get(['stat','load']);
95            
96             # or full link. for example, when using "next" link from previous response
97              
98             $client->get('https://api-metrika.yandex.ru/stat/load/?pretty=1');
99              
100             =cut
101              
102             sub get {
103 0     0 1 0 my ($self, $url, $query) = @_;
104              
105 0         0 return $self->request( 'get', $url, $query );
106             }
107              
108             =item B
109              
110             Send POST request.
111              
112             $client->post(['counters'], {
113             # query params
114             }, {
115             # body params
116             });
117              
118             =cut
119              
120             sub post {
121 0     0 1 0 my ($self, $url, $query, $body) = @_;
122              
123 0         0 return $self->request( 'post', $url, $query, $body );
124             }
125              
126             =item B
127              
128             Send PUT request.
129              
130             $client->put(['counter', $counter_id], {
131             # query params
132             }, {
133             # body params
134             });
135              
136             =cut
137              
138             sub put {
139 0     0 1 0 my ($self, $url, $query, $body) = @_;
140              
141 0         0 return $self->request( 'put', $url, $query, $body );
142             }
143              
144             =item B
145              
146             Send DELETE request.
147              
148             $client->delete(['counter', $counter_id]);
149              
150             =cut
151              
152             sub delete {
153 0     0 1 0 my ($self, $url, $query) = @_;
154              
155 0         0 return $self->request( 'delete', $url, $query );
156             }
157              
158             sub request {
159 0     0 0 0 my ( $self, $method, $url, $query, $body ) = @_;
160              
161 0         0 my $req = HTTP::Request->new( uc $method => $self->make_url( $url, $query ) );
162              
163 0         0 $self->prepare_request( $req, $body );
164              
165 0         0 my $resp = $self->parse_response( $self->ua->request( $req )->content );
166              
167 0         0 return $resp;
168             }
169              
170             sub make_url {
171 4     4 0 25 my ( $self, $resource, $params ) = @_;
172              
173 4 100       23 my @resources = ref $resource ? @$resource : ( $resource );
174              
175 4         9 my $url = '';
176 4 100       21 if ( $resource =~ /^http/i ) {
177 1         3 $url = $resource;
178             }
179             else {
180 3         28 $url = $self->endpoint;
181 3         18 $url =~ s/[\\\/]+$//;
182 3         7 $url .= '/';
183 3         13 $url .= join '/', @resources;
184             }
185              
186 4 100       18 if ( $params ) {
187 2         16 my $uri = URI->new( $url );
188 2         12340 $uri->query_form( %$params );
189 2         279 $url = $uri->as_string;
190             }
191              
192 4         58 return $url;
193             }
194              
195             sub prepare_request {
196 2     2 0 2106 my ( $self, $request, $body_param ) = @_;
197              
198 2         3 my $body = '';
199 2 100       9 if ( $body_param ) {
200 1         144 my $params = dclone( $body_param );
201              
202 1         25 state $json = JSON::XS->new->utf8;
203              
204 1         18 $body = $json->encode( $params );
205              
206 1         13 $request->content( $body );
207             }
208 2         46 $request->header( 'content-type' => 'application/json; charset=UTF-8' );
209 2         171 $request->header( 'content-length' => length( $body ) );
210              
211 2         107 $request->header( 'Authorization' => 'Bearer ' . $self->token );
212              
213 2         102 return 1;
214             }
215              
216             sub parse_response {
217 2     2 0 1619 my ( $self, $response ) = @_;
218              
219 2 100       16 return unless $response;
220              
221 1         8 my $json = JSON::XS::decode_json( $response );
222              
223 1         3 my $next = '';
224              
225 1 50 33     6 if ( defined $json->{links} && defined $json->{links}->{next} ) {
226 0         0 $next = $json->{links}->{next};
227 0         0 $next =~ s/^http:/https:/i;
228              
229 0         0 $self->set_next_url( $next );
230             }
231              
232 1         16 return $json;
233             }
234              
235              
236             1;
237             __END__