I humbly seek wisdom from the Perl Monks:
I'm attempting to write a SOAP server with SOAP::Lite that exposes classes written using Moose (specifically MooseX::Declare). The concept of Perl SOAP clients using SOAP::Lite is not new to me, and I have been able to successfully build a simple SOAP server using the examples in the SOAP::Lite documentation. However, I am not able to translate this limited knowledge to my Moose based classes.
The purpose of my SOAP server is to expose an API my company uses to normalize address data. While the API expects the data in the form of a hashref, I have the same problem passing simple data types to the methods.
The server:
use strict; use API::Translator; use SOAP::Transport::HTTP; SOAP::Transport::HTTP::CGI -> dispatch_to('API::Translator') -> handle;
The Client:
use strict; print "Content-type: text/html\n\n"; my $client = SOAP::Lite->new( uri => 'http://www.example.com/API/Translator/', proxy => [ 'http://sandbox.example.net/api/', credentials => [ 'sandbox.example.net:80', # hostname:port 'EXAMPLE', # realm 'user' => 'password' # username => password ] ] ); my %address = ( 'line1' => '1234 Main Street', 'line2' => 'Apartment X', 'city' => 'Richmond', 'state' => 'Virginia', 'zip' => '23220' ); # Regardless of how or what I pass, I still get the same error: my $result = $client->normalize(SOAP::Data->name('address')->value(\%a +ddress)); #my $result = $client->normalize(\%address); #my $result = $client->normalize('HEY!'); unless ($result->fault) { print $result->result(); } else { print join ', ', $result->faultcode, $result->faultstring; }
The class:
use MooseX::Declare; class API::Translator { use strict; use warnings; has 'normalizer' => ( is =>'rw', isa => 'Address::Normalizer'); # This method throws an error regardless of what I pass it. The er +ror is thrown on the line that defines the method itself, so it doesn +'t matter what code is inside the method. We never get that far. method normalize($address) { require Address::Normalizer; # Initialize the services needed to normalize addresses. $self->normalizer( Address::Normalizer->new->connect('127.0.0. +1', '56789') ); $self->normalizer->normalize($address); return $self->normalizer->response(); } # This function from the SOAP::Lite documentation. This returns d +ata without error. sub f2c { my ($class, $f) = @_; return 5/9*($f-32); } }
The error (paths truncated):
soap:Server, Validation failed for 'MooseX::Types::Structured::Tuple[M +ooseX::Types::Structured::Tuple[Object,Defined],MooseX::Types::Struct +ured::Dict[]]' failed with value [ [ "API::Translator", HASH(0x92c11f +c) ], { } ], Internal Validation Error is: Validation failed for 'Moo +seX::Types::Structured::Tuple[Object,Defined]' failed with value [ "A +PI::Translator", { city: "Richmond", line1: "1234 Main Street", line2 +: "Apartment X", state: "Virginia", zip: 23220 } ] at [...]/MooseX/Me +thod/Signatures/Meta/Method.pm line 443 MooseX::Method::Signatures::M +eta::Method::validate('MooseX::Method::Signatures::Meta::Method=HASH( +0x8f0e660)', 'ARRAY(0x8e603b4)') called at [...]/MooseX/Method/Signat +ures/Meta/Method.pm line 145 API::Translator::normalize('API::Transla +tor', 'HASH(0x92c11fc)') called at [...]/SOAP/Lite.pm line 2797 eval +{...} called at [...]/SOAP/Lite.pm line 2782 eval {...} called at [.. +.]/SOAP/Lite.pm line 2748 SOAP::Server::handle('SOAP::Transport::HTTP +::CGI=HASH(0x91a5170)', '
My first reaction was that MooseX::Types (or derivative) doesn't like the structure of the address hash being sent to it. I spent the better part of a day playing around with setting data types in the class and forcing the SOAP client into different data types. Regardless of what was sent, I'd get some variation of the message above. Even when attempting to send and return a simple string.
What confuses me is that the f2c function works. When I change it to:
method f2c ($f) { return 5/9*($f-32); }
however, I get the same error as above. So I'm pretty confident in saying that the problem is not so much with the data types, but with the order of the expected types, or with how the SOAP server code calls the method itself. Something to do with the method construction rather than its implementation. I haven't a clue whether or not my hunch is true. I'm new to Moose. I'm new to SOAP servers. I'm out of ideas.
Good Perl Monks: please steer me in the right direction. Where am I going astray?
In reply to SOAP::Lite and Moose. Moose and SOAP::Lite by desoto
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |