Net-OpenSocial-Client/lib/Net/OpenSocial/Client/Protocol/REST.pm
package Net::OpenSocial::Client::Protocol::REST;
use Any::Moose;
extends 'Net::OpenSocial::Client::Protocol';
with 'Net::OpenSocial::Client::ErrorHandler';
use Net::OpenSocial::Client::ResultSet;
use Net::OpenSocial::Client::Result;
use Net::OpenSocial::Client::Resource::Factory;
use Net::OpenSocial::Client::Collection;
override 'execute' => sub {
my ( $self, $container, $requests ) = @_;
return $self->ERROR(q{This container doesn't support rest endpoint.})
unless $container->rest_endpoint;
my $result = Net::OpenSocial::Client::ResultSet->new;
for my $request (@$requests) {
my $method = $request->http_method_for_operation();
my %params = %{ $request->params };
my $app_id = delete $params{appId};
my $url = join(
'/',
grep { defined($_) && $_ ne '' } (
$container->rest_endpoint, $request->service,
$request->user_id, $request->group_id,
$app_id,
)
);
$params{format} = $self->formatter->name;
my %build_args = (
method => $method,
url => $url,
params => {%params},
container => $container,
);
if ( $method eq 'POST' || $method eq 'PUT' ) {
unless ( $request->has_resource ) {
return $self->ERROR(q{No resource data found.});
}
my $resource = $request->resource;
$build_args{content_type} = $self->formatter->content_type;
$build_args{content}
= $self->formatter->encode( $resource->fields );
}
my $http_req = $self->request_builder->build_request(%build_args);
my $http_res = $self->agent->request($http_req);
unless ( $http_res->is_success ) {
my $error = Net::OpenSocial::Client::Result->new(
is_error => 1,
code => $http_res->code,
message => $http_res->message,
);
$result->set_result( $request->id => $error );
next;
}
my $res = $self->formatter->decode( $http_res->content );
$result->set_result(
$request->id => $self->_build_result( $request->service, $res ) );
}
return $result;
};
sub _build_result {
my ( $self, $service, $obj ) = @_;
$obj ||= {};
my $result = exists $obj->{response} ? $obj->{response} : $obj;
if ( exists $result->{entry} ) {
my $entries = $result->{entry};
$entries = [$entries] unless ref $entries eq 'ARRAY';
my $coll = Net::OpenSocial::Client::Collection->new;
$coll->total_results( $result->{totalResults} )
if exists $result->{totalResults};
$coll->start_index( $result->{startIndex} )
if exists $result->{startIndex};
$coll->items_per_page( $result->{itemsPerPage} )
if exists $result->{itemsPerPage};
for my $entry (@$entries) {
next unless ( keys %$entry > 0 );
my $resource
= Net::OpenSocial::Client::Resource::Factory->gen_resource(
$service, $entry );
$coll->add_item($resource);
}
return Net::OpenSocial::Client::Result->new( data => $coll );
}
else {
# VOID result
return Net::OpenSocial::Client::Result->new;
}
}
no Any::Moose;
__PACKAGE__->meta->make_immutable;
1;
=head1 NAME
Net::OpenSocial::Client::Protocol::REST - Protocol class for RESTful API.
=head1 SYNOPSIS
my $protocol = Net::OpenSocial::Client::Protocol::REST->new(
formatter => Net::OpenSocial::CLient::Formatter::JSON->new,
request_builder => Net::OpenSocial::Client::HTTPRequestBuilder::OAuth->new(...),
agent => LWP::UserAgent->new,
);
my $result_set = $protocol->execute($container, $requests);
=head1 DESCRIPTION
Protocol class for RESTful API.
=head1 METHODS
=head2 execute($container, $requests)
=head1 SEE ALSO
L<Net::OpenSocial::Client::Protocol>
=head1 AUTHOR
Lyo Kato, E<lt>lyo.kato@gmail.comE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2009 by Lyo Kato
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
=cut