Group
Extension

Yandex-OAuth/lib/Yandex/OAuth/Client.pm

=encoding utf-8

=head1 NAME

Yandex::OAuth::Client - base class for any Yandex.API modules

=head1 SYNOPSIS

    use Yandex::OAuth::Client;

    my $client = Yandex::OAuth::Client->new(token => '************', endpoint => 'https://api-metrika.yandex.ru/');

    my $client->get(['stat','user_vars'], {
            pretty => 1,
            # other params specified for resource
        });
    # url converting to https://api-metrika.yandex.ru/stat/user_vars/?pretty=1

=head1 DESCRIPTION

Yandex::OAuth::Client is base class for any Yandex.API modules
Contains get, post, put, delete methods for queries to any APIs Yandex.

Looking for contributors for this and other Yandex.APIs

=cut

package Yandex::OAuth::Client;
use 5.008001;
use utf8;
use Modern::Perl;
use Data::Dumper;

use LWP::UserAgent;
use Storable qw/ dclone /;
use JSON::XS;
use Moo;

has 'ua' => (
    is => 'ro',
    default => sub {
        my $ua = LWP::UserAgent->new();
        $ua->agent( 'Yandex::OAuth Perl API Client' );
        $ua->timeout( 120 );
        return $ua;
    }
);

has 'token' => (
    is => 'rw',
    required => 1,
);

has 'endpoint' => (
    is => 'rw',
    required => 1,
);

has 'next_url' => (
    is => 'rw',
    default => '',
    writer  => 'set_next_url',
);

has 'demo' => (
    is => 'rw'
);

=head1 CONSTRUCTOR

=over

=item B<new()>

Require two arguments: token and endpoint. For module based on Yandex::OAuth::Client 
you can override atribute 'endpoint'
    
    extends 'Yandex::OAuth::Client';
    has '+endpoint' => (
        is      => 'ro',
        default => 'https://api-metrika.yandex.ru/',
    ); 

=back

=head1 METHODS

=over

=item B<get()>

Send GET request.

    $client->get(['stat','load']);
    
    # or full link. for example, when using "next" link from previous response

    $client->get('https://api-metrika.yandex.ru/stat/load/?pretty=1');

=cut

sub get {
    my ($self, $url, $query) = @_;

    return $self->request( 'get', $url, $query );
}

=item B<post()>

Send POST request.

    $client->post(['counters'], {
            # query params 
        }, {
            # body params
        });

=cut

sub post {
    my ($self, $url, $query, $body) = @_;

    return $self->request( 'post', $url, $query, $body );
}

=item B<put()>

Send PUT request.

    $client->put(['counter', $counter_id], {
            # query params 
        }, {
            # body params
        });

=cut

sub put {
    my ($self, $url, $query, $body) = @_;

    return $self->request( 'put', $url, $query, $body );
}

=item B<delete()>

Send DELETE request.

    $client->delete(['counter', $counter_id]);

=cut

sub delete {
    my ($self, $url, $query) = @_;

    return $self->request( 'delete', $url, $query );
}

sub request {
    my ( $self, $method, $url, $query, $body ) = @_;

    my $req = HTTP::Request->new( uc $method => $self->make_url( $url, $query ) );

    $self->prepare_request( $req, $body );

    my $resp = $self->parse_response( $self->ua->request( $req )->content );

    return $resp;
}

sub make_url {
    my ( $self, $resource, $params ) = @_;

    my @resources = ref $resource ? @$resource : ( $resource );

    my $url = '';
    if ( $resource =~ /^http/i ) {
        $url = $resource;
    }
    else {
        $url = $self->endpoint;
        $url =~ s/[\\\/]+$//;
        $url .= '/';
        $url .= join '/', @resources;
    }

    if ( $params ) {
        my $uri = URI->new( $url );
        $uri->query_form( %$params );
        $url = $uri->as_string;
    }

    return $url;
}

sub prepare_request {
    my ( $self, $request, $body_param ) = @_;

    my $body = '';
    if ( $body_param ) {
        my $params = dclone( $body_param );

        state $json = JSON::XS->new->utf8;

        $body = $json->encode( $params );

        $request->content( $body );
    }
    $request->header( 'content-type'   => 'application/json; charset=UTF-8' );
    $request->header( 'content-length' => length( $body ) );

    $request->header( 'Authorization' => 'Bearer ' . $self->token );

    return 1;
}

sub parse_response {
    my ( $self, $response ) = @_;

    return unless $response;

    my $json = JSON::XS::decode_json( $response );

    my $next = '';

    if ( defined $json->{links} && defined $json->{links}->{next} ) {
        $next = $json->{links}->{next};
        $next =~ s/^http:/https:/i;

        $self->set_next_url( $next );
    }

    return $json;
}


1;
__END__

=back

=head1 LICENSE

Copyright (C) Andrey Kuzmin.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 AUTHOR

Andrey Kuzmin E<lt>chipsoid@cpan.orgE<gt>

=cut



Powered by Groonga
Maintained by Kenichi Ishigaki <ishigaki@cpan.org>. If you find anything, submit it on GitHub.