I wrote a wrapper library for a REST API (https://semantics3.com) in perl using the Moose library. I would like to gather some feedback on it (mainly on the oop part since I am new to moose), before pushing it out.
The full repo is on github: https://github.com/Semantics3/semantics3-perl/
Base class:
has 'debug' => (is => 'rw', isa => 'Bool', default => 0);
has 'api_key' => (is => 'ro', isa => 'Str', required => 1);
has 'api_secret' => (is => 'ro', isa => 'Str', required => 1);
has 'api_base' => (is => 'ro', isa => 'Str', lazy_build => 1);
has 'oauth_client' => (is => 'ro', isa => 'Object', lazy_build => 1);
# Helper methods
method _get {
my $path = shift;
my $json_params = shift;
return $self->_make_request('GET',$path,$json_params);
}
method _make_request {
my $req_type = shift;
my $req_path = shift;
my $req_params_json = shift;
my $url = $self->api_base . '/' . $req_path;
#$req->header( Authorization =>
# "Basic " . encode_base64($self->api_key . ':'));
my $resp;
my $e = eval{
$resp = $self->oauth_client->request(
method => $req_type,
url => $url,
params => {q => $req_params_json}
);
};
if($@) {
$self->_req_error_msg("Request could not be made","","");
}
if ($resp->code == 200) {
my $hash = decode_json($resp->content);
return hash_to_object($hash) if $hash->{object};
if (my $data = $hash->{data}) {
return [ map { hash_to_object($_) } @$data ];
}
return $hash;
}
else {
$self->_req_error_msg("Request failed",$resp->status_line,$resp->content);
}
$e = eval { decode_json($resp->content) };
if ($@) {
$self->_req_error_msg("Could not decode HTTP response",$resp->status_line,$resp->content);
};
#warn "$e\n" if $self->debug;
die "Error occured\n";
}
method _req_error_msg {
my $msg =shift;
my $status_line = shift;
my $content = shift;
print STDERR "Message: $msg\n";
print STDERR "Status Line: $status_line\n";
print STDERR "Content: $content\n";
}
sub hash_to_object {
my $hash = shift;
my $class = 'Net::Semantics3::' . ucfirst($hash->{object});
return $class->new($hash);
}
method _build_api_base { 'https://api.semantics3.com/v1' }
method _build_oauth_client {
my $ua = LWP::UserAgent->new;
$ua->agent("Semantics3 Perl Lib/$VERSION");
my $oauth_client = OAuth::Lite::Consumer->new(
ua => $ua,
consumer_key => $self->api_key,
consumer_secret => $self->api_secret,
);
return $oauth_client;
}
Products.pm
extends 'Net::Semantics3';
use constant MAX_LIMIT => 10;
has 'products_query' => (isa => 'HashRef', is => 'rw', default => sub { my %hash; return \%hash; } );
has 'categories_query' => (isa => 'HashRef', is => 'rw', default => sub { my %hash; return \%hash; } );
has 'query_result' => (isa => 'HashRef', is => 'rw', default => sub { my %hash; return \%hash; } );
has 'sem3_endpoint' => (isa => 'Str', is => 'ro', writer => 'private_set_endpoint', default => "products");
Products: {
#stupid hack to enforce method overloading
method field {
my $field_name = shift || die "A Field Name is required";
my $field_value1 = shift;
my $field_value2 = shift;
if(!defined($field_value1) && !defined($field_value2)) {
die "A Field value is required";
}
if(defined($field_value2)) {
if(!defined($self->products_query->{$field_name})) {
$self->products_query->{$field_name} = {};
}
$self->products_query->{$field_name}->{$field_value1} = $field_value2;
} else {
$self->products_query->{$field_name} = $field_value1;
}
}
method get_products {
$self->_run_query("products",$self->products_query);
return $self->query_result();
}
}
Thanks!