Use perl creating web services with xml rpc


Published on

Published in: Education
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Use perl creating web services with xml rpc

  1. 1. use PerlAll the Perl thats Practical to Extract and Report Creating Web Services with XML-RPCDate 2001.02.05 10:29Author jjohnTopic SOAP. CORBA. Buzzwords galore, but possibly useful ones: this is, essentially,technology that allows you to use web sites as a big API. Below we have an article aboutXML-RPC; you might also want to check out an article by Paul Kulchenko, "Quick Start with SOAP".Web Services Are More Than HTTPOne of Perls enduring strengths is in allowing the programmer to easily manipulate UNIXsystem resources, like /etc/passwd files, syslog and the filesystem. Perl is also a great toolfor building network applications (for more on this, see Lincoln Steins excellent NetworkProgramming with Perl). As Nathan Torkington pointed out at YAPC 19100, the Perlcommunity hasnt yet fully embraced a component model of programming. Components arelibraries that can be used by programs written in any language. If youve dealt with Windowsprogramming particularly ASP coding, you are probably familiar with COM objects already.But COM is just one vendors implementation of components. Jon Udell argues that webapplications can be used in a component fashion. How many of you have stolen the HTMLfrom your favorite search engines FORM and pasted it into your homepage? (I hope Im notthe only one raising my hand!)Although LWP is a powerful tool for "page scraping", you probably dont want to be parsingHTML every time you make an object call. Fortunately, others have been working on thisproblem. XML-RPC is a protocol for Remote Procedure Calls whose conversation over TCPport 80 is encoded into XML. There are XML-RPC implementations written in manylanguages for many platforms, including Perl.Every XML-RPC application must have two parts, but theres a third that ought to berequired. If your script is making an XML-RPC request to some web service, you are makingclient calls. If your script is answering XML-RPC requests, it is a listener. This seems todescribe a typical client-server system; what could be the third piece? Because XML-RPC islanguage and platform neutral, it is essential that the listeners API be adequatelydocumented. Listing what procedures are expecting for input and the datatypes of the returnvalues is a necessity when dealing with sub-Perl languages, like Microsofts VBScript.The XML-RPC protocol is a call and response system, very much akin to HTTP. Oneconsequence of this is that XML-RPC doesnt support transactions or maintaining state.Another problem is the conversation between listener and client is in clear-text. Despite theselimitations, there are still a number of applications for which XML-RPC is well suited.
  2. 2. Building a ClientThe first quandary the novice XML-RPC Perl programmer will encounter is the name of themodule. Ken MacLeods implementation is called Frontier::RPC, because XML-RPC wasthe brain child of UserLands Dave Winer, also of Frontier Naming issues aside, you can findthis module on your local CPAN. Installation follows the normal "perl Makefile.PL &&make test && make install" cycle.Lets assume theres an existing XML-RPC service you want to talk to. It defines thefollowing API:Procedure Name | Input | Output-------------------------------------hello_world | <STRING> | <STRING>-------------------------------------sum | <INT>, | | <INT> | <INT>-------------------------------------- Figure 1Remember, XML-RPC is designed to be language neutral. Every languages implementationof XML-RPC translates the RPC into an XML description that tags each argument with aspecific XML-RPC datatype. Although Perls DWIM-FU is strong, other languages arestrongly typed and need this additional information. When the listener responds,Frontier::RPC translates the XML back into Perl datatypes.Besides the API, we need to know the URL of the listener. For this example, we will use anNT machine on my private network.Enough yakkin. Heres a simple test of this web service. 1 #!/usr/bin/perl -- 2 3 use strict; 4 use Frontier::Client; 5 6 my $rps = Frontier::Client->new( 7 url =>"", 8 ); 9 10 print "Calling hello_world()n"; 11 eval { print $rps->call("hello_world", "jjohn"), "n" }; 12 13 print "n=-----------------=n"; 14 print "Calling sum()n"; 15 eval { print $rps->call("sum", "1024", "128"), "n" }; 16 17 print "ndonen"; Figure 2
  3. 3. After including the library, we instantiate a new Frontier::Client object by passing theURL of the web service. We can now make our RPC by using the call() method, whichexpects the name of the remote procedure followed by a list of its arguments. If all goes well,call() converts the return value of the procedure into a normal Perl datatype. Why am Iwrapping the method calls in evals? According to the XML spec, an XML parser issupposed to halt as soon as it finds a parsing error. Since Frontier::RPC is encoding anddecoding XML, this is a precaution. Sometimes, bad things happen to good network packets.The output looks like this:[jjohn@marian xmlrpc]$ ./test_simpleCalling hello_world()Hello, jjohn=-----------------=Calling sum()1152done Figure 3Sure, strings and numbers are useful but Real Functions ™ use collection types like arraysand dictionaries. XML-RPC can handle those datatypes as well.Heres an example of a procedure that returns an array of hashes. It is getting all the recordsfrom an Access database stored on the aforementioend NT system. Notice that we are talkingto a different XML-RPC listener now. 1 #!/usr/bin/perl -- 2 3 use strict; 4 use Frontier::Client; 5 use Data::Dumper; 6 7 my $rps = Frontier::Client->new( 8 url =>"", 9 ); 10 11 print "nCalling dump_address_book()n"; 12 13 eval { my $aref = $rps->call("dump_address_book"); 14 print Dumper($aref); 15 }; 16 17 print "ndonen"; Figure 4All the usual Frontier::RPC suspects are here. This time, we are explicitly assigning thecall methods return value. A collection type is always returned as a reference by thislibrary. We can use this reference as we would an normal Perl variable, but Data::Dumper isa simple way to verify that the call succeed. For the record, heres a pared down version ofthe output.
  4. 4. [jjohn@marian xmlrpc]$ ./use_perl_taddrsCalling dump_address_book()$VAR1 = [ { email =>, firstname => Macky, phone => 999 555 1234, lastname => McCormack }, { email =>, firstname => Joe, phone => no way, dude!, lastname => Johnston } ];done Figure 5Building a ListenerFor those system administrators out there who want to build a monitoring system for thehealth of each machine on their network, installing simple XML-RPC listeners on eachmachine is one easy way to collect system statistics. Here is the code for a listener thatreturns a structure (really a hash) that is a snapshot of the current system health.#!/usr/bin/perl --use strict;use Frontier::Daemon;Frontier::Daemon->new( methods => { status => sub { return { uptime => (join"<BR>",`uptime`), df => (join "<BR>", `df`), }; }, }, LocalPort => 80, LocalAddr =>, ); Figure 6The Frontier::Daemon class is a sub-class of HTTP::Daemon. The new method doesntreturn; it waits to service requests. Because HTTP::Daemon is a sub-class ofIO::Socket::INET, we can control the TCP port and address to which this server will bind(aint Object Orient Programming grand?). The procedures that XML-RPC clients can call arecontained in the hash pointed to by the methods parameter. The keys of this hash are thenames of the procedures that clients call. The values of this hash are references to subroutinesthat implement the given procedure. Here, there is only one procedure that our service
  5. 5. provides, status. To reduce the display burden on the clients, Im converting newlines intoHTML <BR> tags. Heres a screenshot of an ASP page that is making XML-RPC calls to twomachines running this monitoring service.Documenting Your APILike the weather, everyone talks about documentation but no one ever does anything about it.Without documenting the API to your XML-RPC web service, no one will be able to takeadvantage of it. There is no official way to "discover" the procedures that a web serviceoffers, so I recommend a simple web page that lists the procedure names, the XML-RPCdatatypes expected for input and the XML-RPC datatypes that are returned. Something likeFigure 1 is good a minimum. Of course, it might be nice to explain what those proceduresdo. POD is very amenable to this purpose.Links to More InformationXML-RPC is a great tool for creating platform independent, network application gateways.Its simplicity is its strength. For more information on XML-RPC, check out the homepage at
  6. 6. or wait for the OReilly book Programming Web Applications with XML-RPC, due out this summer.Links 1. "" - 2. "Quick Start with SOAP" - 3. "Network Programming with Perl" -,2627,0201615711,00.html 4. "Jon Udell" - 5. "Ken MacLeod" - 6. "Frontier" - 7. "" - © Copyright 2009 - pudge, All Rights Reservedprinted from use Perl, Creating Web Services with XML-RPC on 2009-06-24 16:11:44