summary refs log tree commit diff
diff options
context:
space:
mode:
authorfranck cuny <franck@lumberjaph.net>2009-11-24 14:18:29 +0100
committerfranck cuny <franck@lumberjaph.net>2009-11-24 14:18:29 +0100
commit5d75c4efc230497d7cc16f3134ad40289b3de022 (patch)
tree601a6c880da2c6350c3ffc8e7e636f44785e5959
parentupdate pod (diff)
downloadmoosex-net-api-5d75c4efc230497d7cc16f3134ad40289b3de022.tar.gz
add support for (de)serialization
-rw-r--r--lib/MooseX/Net/API.pm85
1 files changed, 74 insertions, 11 deletions
diff --git a/lib/MooseX/Net/API.pm b/lib/MooseX/Net/API.pm
index 3fad417..14a10f2 100644
--- a/lib/MooseX/Net/API.pm
+++ b/lib/MooseX/Net/API.pm
@@ -6,14 +6,16 @@ use Try::Tiny;
 
 our $VERSION = '0.01';
 
-our $content_type = {
+our $list_content_type = {
     'json' => 'application/json',
     'yaml' => 'text/x-yaml',
     'xml'  => 'text/xml',
 };
+our $reverse_content_type = { 'application/json' => 'json', };
 
 Moose::Exporter->setup_import_methods(
-    with_caller => [qw/net_api_method format_query require_authentication/], );
+    with_caller => [ qw/net_api_method format_query require_authentication/ ],
+);
 
 sub format_query {
     my ( $caller, $name, %options ) = @_;
@@ -51,14 +53,21 @@ sub net_api_method {
             my $self = shift;
             my %args = @_;
 
+            if (!$self->meta->does_role('MooseX::Net::API::Roles::Deserialize')){
+                MooseX::Net::API::Roles::Deserialize->meta->apply($self);
+            }
+            if (!$self->meta->does_role('MooseX::Net::API::Roles::Serialize')){
+                MooseX::Net::API::Roles::Serialize->meta->apply($self);
+            }
+
             # XXX apply to all
-            if ($options{path} =~ /\$(\w+)/) {
+            if ( $options{path} =~ /\$(\w+)/ ) {
                 my $match = $1;
-                if (my $value = delete $args{$match}) {
+                if ( my $value = delete $args{$match} ) {
                     $options{path} =~ s/\$$match/$value/;
                 }
             }
-            my $url = $self->api_base_url.$options{path};
+            my $url = $self->api_base_url . $options{path};
 
             my $format = $caller->_format($self);
             $url .= "." . $self->format if ( $format->{mode} eq 'append' );
@@ -69,22 +78,36 @@ sub net_api_method {
             my $method = $options{method};
             if ( $method =~ /^(?:GET|DELETE)$/ ) {
                 $uri->query_form(%args);
-                $req = HTTP::Request->new($method => $uri);
+                $req = HTTP::Request->new( $method => $uri );
             }
             elsif ( $method =~ /^(?:POST|PUT)$/ ) {
-                $req = HTTP::Request->new($method => $uri);
+                $req = HTTP::Request->new( $method => $uri );
+
                 # XXX handle POST and PUT for params
             }
             else {
                 croak "$method is not defined";
             }
 
-            $req->header(
-                'Content-Type' => $content_type->{ $format->{format} } )
+            # XXX check presence content type
+            $req->header( 'Content-Type' =>
+                    $list_content_type->{ $format->{format} }->{header} )
                 if $format->{mode} eq 'content-type';
-            #return 1;
+
             my $res = $self->useragent->request($req);
-            return $res->content;
+            if ( $res->is_success ) {
+                my $content_type = $res->headers->{"content-type"};
+                if ( my $type = $reverse_content_type->{$content_type} ) {
+                    my $method = '_from_' . $type;
+                    return $self->$method( $res->content );
+                }
+            }
+            else {
+                return MooseX::Net::API::Error->new(
+                    code  => $res->code,
+                    error => $res->content
+                );
+            }
         };
     }
     else {
@@ -145,6 +168,46 @@ sub new {
 
 }
 
+package MooseX::Net::API::Roles::Deserialize;
+
+use Moose::Role;
+use JSON::XS;
+use YAML::Syck;
+use XML::Simple;
+
+sub _from_json {
+    return decode_json( $_[1] );
+}
+
+sub _from_yaml {
+    return Dump $_[1];
+}
+
+sub _from_xml {
+    my $xml = XML::Simple->new( ForceArray => 0 );
+    $xml->XMLout( { data => $_[0] } );
+}
+
+package MooseX::Net::API::Roles::Serialize;
+
+use Moose::Role;
+use JSON::XS;
+use YAML::Syck;
+use XML::Simple;
+
+sub _to_json {
+    return encode_json( $_[1] );
+}
+
+sub _to_yaml {
+    return Load $_[1];
+}
+
+sub _to_xml {
+    my $xml = XML::Simple->new( ForceArray => 0 );
+    $xml->XMLin("$_[0]");
+}
+
 1;
 __END__