Simplified SOAP Development with SOAP::Lite - Part I
Author: Darshan Singh (Managing Editor, PerfectXML)
Introduction
As of September 2001, there are around seventy (70)
toolkits
available from various sources including Microsoft, Apache, Cape
Clear, and so on, to aid develop SOAP client and/or server applications. The
question is which one should you use? The answer is – it depends! If you are used to Microsoft technologies, you
may go with Microsoft SOAP Toolkit or .NET Framework SDK, depending on which
platform you are developing on; however if you like the "tim-toady" way of programming, the best bet for you
would be to use SOAP::Lite for Perl, developed by Paul Kulchenko.
In this article series, we'll take a detailed look at
SOAP::Lite, a wonderful SOAP Toolkit, and understand how it simplifies the SOAP
development process. This first installment introduces Perl and discusses how
to write SOAP clients using the SOAP::Lite toolkit.
What is "tim-toady"?
In December 1987, Larry Wall announced Perl 1.0 on usenet's alt.comp.sources.
The man page for Perl summarized
it as:
Perl or Practical Extraction and Report Language, is an
interpreted language optimized for scanning arbitrary text files, extracting
information from those text files, and printing reports based on that
information. It's also a good language
for many system management tasks.
From its small start as a text-processing language, Perl
has grown into a sophisticated, general-purpose programming language, and is
one of the most portable programming environments available today, still
maintaining the aim of making the easy
jobs easy, without making the hard jobs impossible. Modern definition of
Perl may sound like:
Perl is a high-level programming language with an eclectic heritage
written by Larry Wall and a cast of thousands. It derives from the ubiquitous C
programming language and to a lesser extent from sed, awk, the Unix shell, and
at least a dozen other tools and languages. Perl's process, file, and text
manipulation facilities make it particularly well-suited for tasks involving
quick prototyping, system utilities, software tools, system management tasks,
database access, graphical programming, networking, and world wide web programming.
These strengths make it especially popular with system administrators and CGI
script authors, but mathematicians, geneticists, journalists, and even managers
also use Perl. Maybe you should, too.
-- CPAN Web site
Remember that Perl is free and available to download at Perl.com
(for UNIX and
OS/2) or from ASPN
(for Microsoft Windows, Linux and Solaris).
"There's More Than One Way To Do It" (TMTOWTDI for short,
pronounced "tim-toady"), is
the Perl Slogan, simply because the language offers great flexibility to
perform a particular task in number of ways.
So, how do you get started with this cool language? The
first step is to download and install Perl environment, so that you can then
run Perl programs. Note that, I wrote all the sample programs for this article
on Microsoft Platform (Windows 2000 Advanced Server is my machine, to be more
specific), I downloaded ActivePerl 5.6.1.629 from ActiveState Web site, and simply ran the install.
However, you should be able to run all the samples from this article, with any
Perl environment on any platform you have. My experience with ActivePerl have
been good and I personally like it, because by just running the ActivePerl
setup, I have complete Perl environment (path variables, etc.) set up and also
access to wonderful documentation and useful code samples. I would highly
recommend you download ActivePerl from ASPN Web site
,
before we write our first simple Perl program, in the next section.
HelloWorld.pl
With Perl, you don't have to say much before you say what
you want to say. Hence, to write a program that simply prints "Hello
World", just following single line is sufficient.
|
HelloWorld.pl
|
|
print
"Hello World!";
|
Open Notepad (or any of your favorite text file editor)
and key in the above print
statement, save the file as HelloWorld.pl and on the DOS command prompt:
Perl HelloWorld.pl
This example assumes that Perl is in the execution path;
if not, either add (ex: c:\perl\bin
for ActivePerl) to path or you will need to supply the full path to Perl.
In Perl, a variable can be one of following five types:
|
Scalar
|
$empName
|
An individual value (number or string)
|
|
Array
|
@phoneNos
|
A list of values, indexed by number
|
|
Hash
|
%resourceStrings
|
A group of name-value pair, indexed by string
|
|
Subroutine
|
&handleError
|
A callable chunk of Perl code
|
|
Typeglob
|
*varFoo
|
Everything named varFoo
|
If you are familiar with the notion of Namespaces, which
are useful for grouping together the logically-related code and to avoid name
collisions, the similar facility is available in Perl with the help of package and use keywords. To
start a new package, say package packageName,
and to use/borrow the nouns and verbs of an existing package, say use packageName.
The concept of package (also called module) brings the facility of reusability.
That means you can directly reuse the code (modules) written by somebody else
and save some time. CPAN (Comprehensive Perl
Archive Network)
Web site contains a large collection of Perl software modules
and documentation, including SOAP::Lite
.
The complete tutorial discussion on Perl is out of the
scope of this article. Review the References section
to find links and other resources to learn more about Perl. In this article,
we'll have a brief look at Perl.
Perl Basics
Operators:
+, -, % (Modulus), ** (Exponentiation), . (period for string
concatenation), x (repeat operator), = (assignment), ++ (auto-increment), --
(auto-decrement), && (logical AND), || (logical OR), ! (logical Not), and, or, not, Xor, == (Equal), !=, <, >,
<=, >=, <=> (comparison), eq (string equality), ne, lt, gt, le, ge,
cmp, -e (file exists operator), -r (file is readable), -w (writable), -d
(directory), -f (regular file), -T (text file), ? : (conditional operator),
<< (left shift), >> (right shift).
Example:
$var1 = 4;
$var2 = 2;
|
print $var1 + $var2;
|
6
|
|
print $var1 - $var2;
|
2
|
|
print $var1 % $var2;
|
0
|
|
print $var1 / $var2;
|
2
|
|
print $var1 * $var2;
|
8
|
|
print $var1 . $var2;
|
42
|
|
print $var1 x $var2;
|
44
|
|
print $var1 << $var2
|
16
|
It's important to remember that any string is true except
for "" and "0", any number is true except for 0, and any
undefined value is false.
Perl provides if,
if..else,
if..elseif,
and unless control statements; while,
until, for, foreach looping
constructs.
At the heart of Perl's strongest feature, text processing,
is Regular Expressions (also known as RegExs, RegExps, or REs). Regular
expressions are used to match pattern in order to search large amounts of data
conveniently and efficiently.
|
RegExps.pl
|
|
$_='12:59:33 am';
($varHour) = /(\d+)/;
print "Hour is : $varHour\n";
#replace am with AM
$_ =~ s/am/AM/;
print $_;
|
The above example illustrates couple of things including
use of Regular Expressions. The first line initializes a special scalar
variable $_ with some time
value.
In Perl, $_ is
a special scalar variable, also known as default string, used by Perl pattern
matching and many other operators as the default string to operate on, if no
other string scalar variable is specified. That's what is happening in the next
line in the code, which uses a regular expression to search for one or more
digits (and stop as soon as non-digit character is found) and assign the value
to $varHour scalar variable.
Comments in Perl are written using the # symbol.
Note that in Perl, including strings in either single or
double quotes have a different meaning. A single quoted string is a pure plain
string without interpolation, while
the double quoted string is a string with interpolation
that means they can refer to other variables and identifiers, whose values will
be expanded before spitting the final string. Try replacing the double quotes
with single quotes in the first print
statement and you'll notice the difference.
Next, we use the substitution operator and replace the
first occurrence of word "am"
with "AM". Finally,
save the replaced string in default string and print it. The output looks like:
With this little introduction to Perl language, let's now
move our focus to programming with SOAP::Lite. Once again, remember to look at References section to learn more about Perl.
Enter SOAP::Lite for Perl
"The Power of
Simplicity" is the SOAP::Lite Slogan. With this section, we'll begin
looking at SOAP::Lite in greater depth and illustrate how SOAP::Lite simplifies
the SOAP development.
SOAP::Lite for Perl is a collection of Perl modules which provides a
simple and lightweight interface to the Simple Object Access Protocol (SOAP,
also known as Service Oriented Access Protocol) both on client and server side.
-- SOAPLite.com
Paul Kulchenko
,
with over ten years of experience in design and development of complex
financial and banking applications, and information management in the financial
services sector, started working on SOAP::Lite about a year ago, when he was
designing an internet-based payment system. Today, Paul manages the SOAP::Lite
module, the XMLRPC::Lite module that implements XML-RPC protocol, and the
UDDI::Lite module, a client interface for UDDI repositories.
It is important to remember that the word 'Lite' in the toolkit name
refers to the simple and lightweight interface it provides, and not to missing
features. In other words, 'Lite' refers to the effort it takes to use the
module, not its capabilities.
The latest SOAP::Lite version (0.51) is freely available
to download from SOAPLite.com
and CPAN.org
, for both Unix and Win32 platforms. This version of SOAP::Lite
supports most of the SOAP 1.1, SOAP 1.2 and SOAP Messages with Attachments
specifications. Go ahead and download the toolkit and unzip/unpack the .zip or
.gz files into some directory.
Remember that, if you installed ActivePerl 5.6.1.629, it installs 0.46
version of SOAP::Lite module. You may safely copy (overwrite) all the subdirectories
under lib
from SOAP::Lite extracted directory to
ActivePerl lib directory (mostly C:\Perl\lib). And then
you may run:
perl -MSOAP::Lite
-e "print SOAP::Lite->VERSION"
on the command prompt to verify the SOAP::Lite module version. Just a
sidenote, you can check the Perl version too by running "Perl –v" on
the command prompt.
Connecting to SOAP Web Services
I think the easiest way to start learning SOAP::Lite is to
start writing few small Perl script programs that connect to existing public
SOAP Web Services. Web sites like XMethods
and SalCentral
hold a list of these
Web services.
In this section we'll write five SOAP::Lite client
programs, two connecting to .NET Web services, one to Apache SOAP service, one
to Microsoft SOAP service and the last one to SOAP service written using CapeConnect.
.NET Client - I
Let's start with a SOAP::Lite client application that
connects to SalesRankNPrice
,
a Web Service created using ASP.NET, and can be used to get Amazon.com and/or
BarnesAndNobel.com Sales Rank and/or Price for any book, given the ISBN number
|
dotNetClient.pl
|
|
#!perl -w
use
SOAP::Lite;
my $s =
SOAP::Lite
->
uri('http://www.perfectxml.com/NETWebSvcs/BookService')
->
proxy('http://www.PerfectXML.NET/WebServices/SalesRankNPrice/BookService.asmx')
-> on_action(sub{sprintf '%s/%s', @_
})
;
my $ISBN =
SOAP::Data->name('ISBN' =>
1861005466)->type('string')->uri('http://www.perfectxml.com/NETWebSvcs/BookService');
$result =
$s->GetAll($ISBN)->result; # hash with elements
print
$result->{AmazonSalesRank}, "\n";
print
$result->{AmazonPrice}, "\n";
print
$result->{BNSalesRank}, "\n";
print
$result->{BNPrice}, "\n";
|
Open Notepad and type (or copy and paste) above few lines
of Perl code and save the file as dotNetClient.pl.
The first line in the above code is the
"shebang" notation that tells the shell where to find the Perl
interpreter. The important point in "shebang" line is the –w switch
that is passed to the interpreter, which turns on interesting warning messages,
useful during development. Next, we tell the interpreter that we would like to
use the SOAP::Lite module.
We then create an instance representing the remote class.
This way, we can then directly call methods on the remote class using this
newly created object. While creating the instance of the remote class, we do
three things in the above code:
1. Specify
the method namespace (uri),
2. Specify
Service Endpoint URL (proxy),
and
3. Customize
SOAPAction header (on_action)
The third step is not always required. By default,
SOAP::Lite generates a SOAPAction header with the structure of [URI]#[method], however the above service (SalesRankNPrice)
requires the format of [URI]/[method].
By using the on_action method,
we achieve this customization.
Next, we create a scalar variable ($ISBN), and set its data type, namespace URI and finally
assign it a value (some ISBN number). This variable is passed as a parameter to
SOAP Service method call GetAll, which returns the Sales Ranks and Prices for
that book as a hash with elements. We then simply print the result hash element
values.
Should produce output similar to:
|
5,665
$34.99
36,956
$39.99
|
.NET Client – II
Let's look at yet another SOAP::Lite client which connects
to ASP.NET Web Service. This time we'll connect to DotnetDailyFact
Web Service.
|
dotNetClient2.pl
|
|
#!perl -w
use
SOAP::Lite;
my $s =
SOAP::Lite
->
uri('http://xmlme.net/webservices/')
->
proxy('http://v003u23wlw.net.maximumasp.com/V2WSDailyNet.asmx')
-> on_action(sub{sprintf '%s%s', @_
})
;
print "DotNET Daily Fact (" . localtime() . "):\n";
$result =
$s->GetDotnetDailyFact()->result;
print $result,
"\n";
|
Open Notepad and type (or copy and paste) above few lines
of Perl code and save the file as dotNetClient2.pl. You can then
run it by saying Perl dotNetClient2.pl on the DOS command prompt.
The above code is very similar to that in first example.
The only difference is that as the method namespace of this web service already
has a forward slash at the end of namespace, the on_action statement looks little
different (no /
between two "%s"s).
While developing these samples, I found two debugging utilities very
useful. The first one is provided by SOAP::Lite: -> on_debug(sub{print@_})
Try adding ->
on_debug(sub{print@_}) before semicolon (;) line and after
on_action line in the above code and when you run the code, you'll see the
complete request and response SOAP payloads including the headers. The other
useful debugging aid is the SOAP Trace utility that comes with Microsoft SOAP
Toolkit. See references section to find more information about Microsoft SOAP
Toolkit.
Apache SOAP Client
The Weather-Temperature
Web Service on XMethods is a Apache implementation.
Let's see how the SOAP::Lite client that connects to this service,
looks like:
|
apacheClient.pl
|
|
#!perl -w
use
SOAP::Lite;
my $s = SOAP::Lite
-> uri('urn:xmethods-Temperature')
->
proxy('http://services.xmethods.net:80/soap/servlet/rpcrouter')
;
$ZipCode =
$ARGV[0] or die "Usage: $0 zipcode\n";
print
"\nThe temperature in ZipCode $ZipCode is ";
print $s
-> getTemp(SOAP::Data->name('zipcode')->type(string
=> $ZipCode))
-> result;
print
"F\n";
|
The above code takes a command line parameter, a Zip code,
connects to Weather-Temperature Web service and returns a number indicating
temperature in that zipcode area.
Client to Microsoft SOAP Implementation
ITFinity
Currency Conversion
is a Web Service that provides currency conversion
service and is implemented using Microsoft SOAP Toolkit. Let's look at the
SOAP::Lite client code that connects to this SOAP Web Service:
|
msSoapClient.pl
|
|
#!perl –w
use
SOAP::Lite;
my $s =
SOAP::Lite
->
uri('http://www.itfinity.net/soap/exrates/exrates.xsd')
->
proxy('http://www.itfinity.net:8008/soap/exrates/default.asp')
;
$FromCode =
$ARGV[0];
$ToCode =
$ARGV[1] or die "Usage: $0 fromCountryCode toCountryCode\n";
$result =
$s->GetRate(
SOAP::Data->name('fromCurr')->type(string => $FromCode),
SOAP::Data->name('ToCurr')->type(string => $ToCode)
)->result;
print
$result;
|
This client application, takes two command line
parameters, the from country currency
code and to country currency code,
and returns the exchange rate per unit.
Client to CapeConnect authored Web Service
The AirportWeather
Web Service reports on weather at all airports and airfields that have a
registered ICAO (International Civil Aviation Organization) number. This Web
Service is implemented using CapeConnect 2.1. Let's write a SOAP::Lite Perl
client application that connects to this Web service.
|
capeClient.pl
|
|
#!perl -w
use
SOAP::Lite;
my $s =
SOAP::Lite
->
uri('capeconnect:AirportWeather:com.capeclear.weatherstation.Station')
->
proxy('http://www.capescience.com/ccgw/GWXmlServlet')
;
#Sample ICAO
Codes
#Chicago=KORD, New York=KJFK,
Seattle=SEA
$result =
$s->getSummary($ARGV[0] or die "Usage: $0
airportICAOcode\n")->result;
print
"Weather Report for ", $result->{location}, "\n";
print
"------------------------------------------\n";
print
"Wind: ", $result->{wind}, "\n";
print
"Sky: ", $result->{sky}, "\n";
print
"Visibility: ", $result->{visibility}, "\n";
print
"Pressure: ", $result->{pressure}, "\n";
print
"Humidity: ", $result->{humidity}, "\n";
print
"--------------------------------------\n";
|
Open Notepad, type in above code and save the file as capeClient.pl. Run the client
application using Perl capeClient.pl
<airport ICAO Code>.
Summary
This first installment in the series of articles on
SOAP::Lite, focused mainly on introducing Perl, introducing SOAP::Lite and
writing few simple SOAP client applications using the simple yet powerful
SOAP::Lite toolkit. In the coming weeks, we'll see more examples of how
SOAP::Lite simplifies the SOAP Server and Client development and some advance
techniques. Stay tuned!
Download this article in Word document format along with sample Perl script files.
If you have any questions or comments, feel free to contact author of this article, Darshan Singh at darshan@perfectxml.com
.
References
[All external links]
Perl Resources:
·
Perl.com
·
Perl.org
·
Programming
Perl 3rd edition (http://www.amazon.com/exec/obidos/ASIN/0596000278/theultimxmlso-20)
·
Perl Fast Facts (http://www.perl.org/press/fast_facts.html)
·
Per's timeline (http://history.perl.org/PerlTimeline.html)
·
Perl Tutorials (http://www.perlmonks.org/index.pl?node=Tutorials)
·
ActivePerl
(http://aspn.activestate.com/ASPN/Perl/)
·
Perl FAQ a
Day (http://perl.faq-by-day.org/)
·
Perl for Win32 (http://www.northbound-train.com/perlwin32.html)
·
ActivePerl
Documentation (http://aspn.activestate.com/ASPN/Perl/Products/ASPNTOC-ACTIVEPERL)
·
Windows
Services for UNIX version 2 (http://www.microsoft.com/technet/treeview/default.asp?url=/TechNet/prodtechnol/windows2000serv/deploy/sfu/sfu.asp)
·
Perl
Primer (http://builder.cnet.com/webbuilding/pages/Programming/Perl/?tag=st.bl.7704.rt_col.bl_Perl)
·
Cute Tricks With
Perl and Apache (http://stein.cshl.org/~lstein/talks/perl/perl98.html)
SOAP::Lite Resources
·
SOAPLite.com
(http://www.SOAPLite.com)
·
SOAPLite Discussions
(http://groups.yahoo.com/group/soaplite/)
·
Quick Start with SOAP (http://www.perl.com/pub/a/2001/01/soap.html)
·
Part II (Quick Start)
(http://www.perl.com/pub/a/2001/04/24/soap.html)
·
The
Evolution of SOAP::Lite (http://www.onlamp.com/pub/a/onlamp/2001/06/29/soap_lite.html)
·
Using
SOAP::Lite with Perl (http://www-106.ibm.com/developerworks/webservices/library/ws-xpc3.html)
·
Impress
Women II (http://www.perlmonks.org/index.pl?node_id=110217&lastnode_id=1044)