9.4.2. Second Example: An ISBN Lookup Engine
This example, which uses a little module residing on one of the
author's personal web servers, is somewhat more
object oriented. It takes an ISBN number and returns Dublin Core XML
for almost any book that might match it:
my ($isbn_number) = @ARGV;
use SOAP::Lite +autodispatch=>
uri=>'http://www.jmac.org/ISBN',
proxy=>'http://www.jmac.org/projects/bookdb/isbn/lookup.pl';
my $isbn_obj = ISBN->new;
# The 'get_dc' method fetches Dublin Core information
my $result = $isbn_obj->get_dc($isbn_number);
The magic here is that the module on the host machine,
ISBN.pm, isn't unusual in any
way; it's a pretty straightforward Perl module that
you could use in the usual fashion, if you happened to have a local
copy. In other words, we can get the same results by logging into the
machine and hammering out a little program like this:
my ($isbn_number) = @ARGV;
use ISBN; # This line replaces the long 'use SOAP::Lite' line
my $isbn_obj = ISBN->new;
# The 'get_dc' method fetches Dublin Core information
my $result = $isbn_obj->get_dc($isbn_number);
But, by invoking SOAP::Lite and mumbling a few
extra incantations to aim our sights at a remote machine
that's listening for SOAP-ish requests, you
don't need a copy of that Perl module on your end to
enjoy the benefits of its API. And, if we eventually went insane and
reimplemented the module in Java, you'd probably
never know it, since we'd keep the interface the
same. In the language-independent world of web services,
that's all that matters.
Where is the XML? We can switch on a valve and peek at the raw stuff
roaring beneath this pleasant veneer. Let's see what
actually happens with that ISBN class constructor call after we
activate SOAP::Lite's
outputxml option:
my ($isbn_number) = @ARGV;
use SOAP::Lite +autodispatch=>
uri=>'http://www.jmac.org/ISBN', outputxml=>1,
proxy=>'http://www.jmac.org/projects/bookdb/isbn/lookup.pl';
my $isbn_xml = ISBN->new;
print "$isbn_xml\n";
What we get back is something like this:
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENC="http://
schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.
org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:
xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/
XMLSchema" xmlns:namesp1="http://www.jmac.org/ISBN"><SOAP-ENV:Body><namesp2:
newResponse xmlns:namesp2="http://www.jmac.org/ISBN"><ISBN xsi:type="namesp1:ISBN"/>
</namesp2:newResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
The second bit of example code had to stop short, of course, since it
returned a scalar containing a pile of XML (which we then
printed) instead of an object belonging to the
SOAP::Lite class family. We can't
well continue calling methods on it. We can fix this problem by
passing the blob to the magic SOAP::Deserializer
class, which turns SOAPy XML back into objects:
# Continuing from the previous snippet...
my $deserial = SOAP::Deserializer->new;
my $isbn_obj = $deserial->deserialize($isbn_xml);
# Now we can continue as with the first example.
A little extra work, then, nets us the raw XML as well as the black
boxes of the SOAP::Lite objects. As you may
expect, this feature has uses far beyond interesting book examples,
as getting the raw XML in hand opens up the door to all kinds of
interesting mischief on our end.
That's all for our sampling of Perl and XML
applications. Next, we'll talk about some strategies
for building our own applications.