http://qs321.pair.com?node_id=562243

mrguy123 has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I apologize in advance for the length of this one:
My job for the past few months has been retrieving webpages from the internet for a meta search engine. Until now I have done so using basic url queries (e.g  http://www.imdb.com/finds=all&q=cats for all movies with cats in the title). For this I have used the LWP::UserAgent with much satisfaction. In the past few weeks I have been trying to understand and retrieve web pages with SOAP. The information I had in my hand on how to do so (besides the web) were a few programs that my predecessor wrote that uses SOAP. In all these programs but one, he used the LWP::UserAgent to retrieve the web pages, sending the SOAP content as part of the request object in POST. This demo is an example of such a search request (it needs IP-authentication to work, but it sends all the required information):
#!/usr/bin/perl use HTTP::Cookies; use strict; use LWP::UserAgent; { my $ua = new LWP::UserAgent; $ua->cookie_jar(HTTP::Cookies->new()); push @{$ua->requests_redirectable}, 'POST'; my $search_command = "http://wok-ws.isiknowledge.com/esti/soap/Sea +rchRetrieve"; my $content = '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Env +elope xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOA +P-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="htt +p://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/ +1999/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/so +ap/encoding/"><SOAP-ENV:Body><namesp1:search xmlns:namesp1="http://wo +k-ws.isiknowledge.com/esti/soap/SearchRetrieve?wsdl"><databaseId xsi: +type="xsd:string">DIIDW</databaseId><query xsi:type="xsd:string">TS=( +create)</query><editions xsi:type="xsd:string"/><firstRec xsi:type="x +sd:int">1</firstRec><numRecs xsi:type="xsd:int">1</numRecs></namesp1: +search></SOAP-ENV:Body></SOAP-ENV:Envelope>'; my $header = new HTTP::Headers ( 'Content-Type' => 'text/xml; charset=utf-8', 'User-Agent' => 'PHP SOAP 0.1', 'Content-Type' => 'text/xml; charset=utf-8', 'SOAPAction' => "http://wok-ws.isiknowledge.com/esti/soap +/SearchRetrieve?wsdl#search", ); my $req = new HTTP::Request('POST',$search_command,$header,$conten +t); my $res = $ua->request($req); print $req->as_string."\n"; my $response = $res->headers_as_string(); my $response .= $res->content; print "---response---\n$response\n"; }
As I have said, this was the way most of the programs sent their info. However, this particular program used the SOAP::Lite module to create the same search request. The code is:
#!/exlibris/metalib/m4_b/product/bin/perl sub BEGIN { unshift (@INC, $ENV{'aleph_ext'}); unshift (@INC, "$ENV{'aleph_product'}"."/perl/lib/site_perl/5.005" +); unshift (@INC, "$ENV{'aleph_product'}"."/perl/lib/site_perl/5.005/ +i686-linux"); } use SOAP::Lite+trace => 'debug'; my $soap_request = SOAP::Lite->new(); $soap_request->uri("http://wok-ws.isiknowledge.com/esti/soap/SearchRet +rieve?wsdl"); $soap_request->proxy("http://wok-ws.isiknowledge.com/esti/soap/SearchR +etrieve"); $service = 'search'; my $soap_response = $soap_request->$service( SOAP::Data->name(databaseId => 'DIIDW'), SOAP::Data->name(query => 'TS=(create)'), SOAP::Data->name(editions => ""), SOAP::Data->name(firstRec => '1'), SOAP::Data->name(numRecs => '1'), );
As you can see, the code is much more simple, and basically creates the same request from scratch. If you run both demos, you should get the same output. In fact, I built the first demo from the second, using the info that was sent through the module to "convert" the transaction. However, when I tried to convert the other programs from the LWP::UserAgent form of transaction to the SOAP::Lite form, I failed miserabely.
Looking at the SOAP::Lite module in CPAN, I haven't been able to find explanations about how to create a SOAP request like my predacessor did(e.g. how do you know what the soap action is). My questions are (and again, sorry for the length):
1) When should I use the LWP::UserAgent, and when should I use SOAP::Lite?
2) When using SOAP::Lite, how and when can I build the SOAP content from scratch. What should I use for the SAOP action (In my demo it was the uri with a prefix, but is that the how its done all the time)?
3) What advantages does SOAP::WSDL give me over SOAP::Lite. Is it more recommended?

Any links to examples and info sites will be greatly appreciated.
Thanks a lot
Guy Naamati (mrguy123)

The rain it raineth on the just, and also on the unjust fella,
But chiefly on the just, because the unjust steals the just's umbrella.

-- Lord Bowen

2006-07-19 Retitled by holli, as per Monastery guidelines
Original title: 'SOAP::Lite vs LWP::UserAgent for SOAP transcations'

Replies are listed 'Best First'.
Re: SOAP::Lite vs LWP::UserAgent for SOAP transactions
by jhourcle (Prior) on Jul 19, 2006 at 12:44 UTC
    1) When should I use the LWP::UserAgent, and when should I use SOAP::Lite?

    Use SOAP::Lite when you want the extra abstraction and less work -- as it supports multiple encodings, it will likely be more forgiving of returned structures should they change schemas. Use LWP::UserAgent when you have special serialization / deserialization needs that can't be met with SOAP::Lite. (which is actually very unlikely, as you can pass alternate serializers / deserializers to a SOAP::Lite object)

    2) When using SOAP::Lite, how and when can I build the SOAP content from scratch. What should I use for the SAOP action (In my demo it was the uri with a prefix, but is that the how its done all the time)?

    Look through the SOAP::Serializer section of SOAP::Lite. (I've completely overridden the deserialize method in SOAP::Deserializer, but I've never tried doing it with the serializer)

    3) What advantages does SOAP::WSDL give me over SOAP::Lite. Is it more recommended?

    SOAP::WSDL came along after I started playing with SOAP::Lite, and I never played with it, as it's still listed as an alpha release. I know that the SOAP::Lite has improved its WSDL support since the two came out, but I don't know how the two compare, as I don't use that functionality.

    oh -- and you may want to ask your questions on the SOAP::Lite mailing lists, as I don't know how many people on the lists read this site.

      Thanks for your reply,
      Do you know if there is a way to build the http header using SOAP::Lite?

        You can get the HTTP::Request object that will be used with:

        $soap->transport->http_request()
        and you can manipulate that appropriately.

        However if you simply need to construct a SOAPAction header then that is possible through SOAP::Lite's on_action method.

        /J\

Re: SOAP::Lite vs LWP::UserAgent for SOAP transactions
by rob_au (Abbot) on Jul 19, 2006 at 12:25 UTC

    There are few ways to look at this question - Whereas, in it's most basic form, asking where to use LWP::UserAgent in place to SOAP::Lite, is right and appropriate, this query in truth probably raises more questions than it answers. The reason is because, where as LWP::UserAgent provides an appropriate transport conduit for a pre-fashioned XML request, it is not immediately comparable to SOAP::Lite as the latter not only provides transport for a variety of access modalities (such as HTTP, TCP and FTP), but also methods for abstraction for the submitted request, response received and contained data structures. As such, in turn, the question should instead be fashioned around the context of where this code implementation is to be employed - Is there likely to be later changes in transport or data structure? Is there likely to be any variance in structure or form of the responses which are likely to be received? How complex are the responses from the SOAP service likely to be? Is there a requirement for abstraction of the lower-level transport for employ within higher-level applications or APIs?

    These questions are likely to provide a better construct within which to answer your questions than those which you have posed in your post.

     

    perl -le "print unpack'N', pack'B32', '00000000000000000000001000000000'"