package Megaport::Client;
use 5.10.0;
use strict;
use warnings;
our $VERSION = "1.00";
use Carp qw(carp cluck);
use JSON::XS;
use HTTP::Request;
use LWP::UserAgent;
use Class::Tiny qw(token uri no_verify debug errstr), {
ua => sub { LWP::UserAgent->new(agent => __PACKAGE__ . '/' . $VERSION) }
};
sub login {
my ($self, $args) = @_;
if (exists $args->{token}) {
$self->token($args->{token});
return $self->no_verify ? $self : $self->verify;
}
if ($args->{username} && $args->{password}) {
my $response = $self->ua->post($self->uri . '/login', {
username => $args->{username},
password => $args->{password}
});
$self->_dump_response($response) if $self->debug;
my $obj;
eval { $obj = decode_json $response->decoded_content };
if ($@) {
$self->errstr('LoginError: API did not return valid JSON') and return;
}
if (!$response->is_success || !$obj->{data}->{session}) {
$self->errst('LoginError: ' . $obj->{message}) and return;
}
$self->token($obj->{data}->{session});
return $self->no_verify ? $self : $self->verify;
}
}
sub verify {
my ($self) = @_;
my $response = $self->ua->post($self->uri . '/login/' . $self->token);
$self->_dump_response($response) if $self->debug;
if (!$response->is_success) {
$self->_dump_response($response) if $self->debug;
$self->errstr('LoginError: Verifying session token failed')
}
return $self;
}
sub request {
my ($self, $op, $path, %args) = @_;
my $headers = [
'X-Auth-Token' => $self->token,
exists $args{headers} ? @{$args{headers}} : ()
];
my $uri = $self->uri . $path;
my $request = HTTP::Request->new($op => $uri, $headers);
$request->content($args{content}) if $args{content};
my $response = $self->ua->request($request);
$self->_dump_response($response) if $self->debug;
my $obj;
eval { $obj = decode_json $response->decoded_content };
if ($@) {
$self->errstr('RequestError: API did not return valid JSON') and return;
}
if (!$response->is_success) {
$self->errst('RequestError: ' . $obj->{message}) and return;
}
return $obj->{data};
}
sub _dump_response {
my ($self, $response) = @_;
my @error = split /\n/, $response->as_string;
$_ = " > $_" foreach @error;
say STDERR "================ [ DEBUG ] ================";
say STDERR ' > ' . $response->request->method . ' ' . $response->request->uri . "\n";
say STDERR join("\n", @error);
cluck if !$response->is_success;
say STDERR "===========================================\n";
}
1;
__END__
=encoding utf-8
=head1 NAME
Megaport::Client
=head1 DESCRIPTION
This class provides a simple mechanism for making API calls and performing error handling and returning data in a well-known format intended for use in the rest of the L<Megaport> package.
=head1 METHODS
=head2 login
Performs the appropriate login action based on the credentials provided (C<username/password> or C<token>).
=head2 verify
If C<no_verify> is not set, this is called by C<login> to validate the token.
=head2 request
# Simple GET
my $data = $client->request(GEt => '/locations');
# POST
my $data = $client->request(POST => '/profile', content => encode_json($user));
Performs a HTTP request, arguments are similar to L<HTTP::Request> but trimmed. Creates a L<HTTP::Request> object with the right base URI and auth headers.
If C<debug> is set, this will also dump the response body to STDERR.
=head1 AUTHOR
Cameron Daniel E<lt>cdaniel@cpan.orgE<gt>
=cut