XML-RPC: a Next-Generation Web API

Simple, elegant, and useful applications of Internet technology always put a smile on my face. One such application is running at http://www.mailtothefuture.com/. It enables you to send mail to yourself (or, actually, anyone) at some future date.

This is an interactive application that, because it’s a CGI-based web service, I could with a little effort also use as an HTTP-based reminder component built into a groupware or workflow system of my own devising. To do that, I’d follow the procedures outlined earlier: discover the web API, and write a script to control it.

But the author of MailToTheFuture, Dave Winer, has taken this game to a new level. A pioneer in understanding and applying XML, Dave cooked up a marvelously simple and elegant idea that he calls XML-RPC (see http://www.scripting.com/frontier5/xml/code/rpc.html). In a nutshell, it’s a way of formalizing the CGI interface to a web-based service using XML to define both the methods supported by a service and the data marshaling used when communicating with a service.

The architecture of XML-RPC is gloriously simple. A service that supports XML-RPC, such as MailToTheFuture, responds to method calls that are nothing more than HTTP POST requests with XML-formatted payloads. For example, to add a new message to your queue at MailToTheFuture, you invoke the method:

mailToTheFuture.addMessage(username, password, msgstruct)

To use this method, you post an XML-RPC request that expresses that method name and its three parameters. Example 14.1 is a Perl script that illustrates one of the (infinitely many) easy ways to form and transmit such a request. The XML-RPC request appears in literal form following the script’s __END__ directive.

Example 14-1. Invoking the mailToTheFuture.addMessage Method from Perl

#! /usr/bin/perl -w
#
# This script implements the addMessage method at Dave Winer's
# www.MailToTheFuture.com site, using XML-RPC.
#
my $req_data = join('', <DATA>);                  # slurp the XML from __END__ zone

use strict;
use LWP;
my $ua = new LWP::UserAgent;                      # make a user agent
my $req = new HTTP::Request 'POST';               # make a request

$req->url('http://www.mailtothefuture.com/RPC2'), # set url
$req->header(Host => "yourhost");                 # Host: yourhost
$req->user_agent($ua->agent);                     # User-Agent: libwww-perl/5.36
$req->content_type('text/xml'),                   # Content-Type: text/xml
$req->content_length(length($req_data));          # Content-Length: 762
$req->content($req_data);                         # append request data

my $res = $ua->request($req);                     # send the request

if ($res->is_success) 
  { print $res->content;  }                       # echo response
else 
  { print "Could not transmit request
"; }

__END__
<?xml version="1.0"?>
<methodCall>
  <methodName>mailToTheFuture.addMessage</methodName>
    <params>
      <param>
         <value>[email protected]</value>
      </param>
      <param>
         <value>yourpassword</value> 
      </param>
      <param>
         <value>
          <struct>
            <member>
              <name>dateTime</name>
              <value>5/23/99; 11:15:00 AM</value>
            </member>
            <member>
              <name>messageBody</name>
              <value>test message body</value>
            </member>
            <member>
              <name>receiverMailAddress</name>
              <value>[email protected]</value>
            </member>
            <member>
              <name>subject</name>
              <value>test message subject</value>
            </member>
          </struct>
        </value>
      </param>
    </params>
</methodCall>

Anatomy of an XML-RPC Transaction

An XML-RPC request can be as easily read and written by a human as by a program. That’s one of the great features of all Internet software: the protocols (HTTP, SMTP, NNTP) are text based and therefore easy to understand and manipulate in any programming language.

Of course, the same thing applies to ordinary web-client scripting. What’s special about XML-RPC? Well, consider the response that comes back when you send the wrong password to the MailToTheFuture service using its normal CGI interface:

“Sorry! There was an error: Can’t send you the cookie for ‘[email protected]’ because the password is incorrect.”

You can certainly teach your script to recognize and deal with these kinds of responses, but it’s going to be a fragile mechanism. You’re relying on free-form text patterns, and when they change, your script will break.

Now consider the response that comes back from MailToTheFuture’s XML-RPC interface when you send the wrong password:

<?xml version="1.0"?>
<methodResponse>
  <fault>
    <value>
      <struct>
        <member>
          <name>faultCode</name>
          <value>
            <int>4</int>
            </value>
          </member>
        <member>
          <name>faultString</name>
          <value>
            <string>The password is incorrect.</string>
            </value>
          </member>
        </struct>
      </value>
    </fault>
  </methodResponse>

Like the request, this response is well formed—and thus automatically parsable—XML. Every XML-RPC service will use this same pattern. It’s true that, for each application, you’ll need to decide how to handle faultCode 4. But you won’t need to guess that the output is an example of a methodResponse or that its value is a fault object containing a struct made up of a faultCode and a faultString.

Other XML-Formatted Request/Response Protocols

This notion of a standard, human-readable-and-writable, script-parsable lingo for requests and responses is a lot more in tune with the ecology of the Web than DCOM, CORBA, or RMI. It’s all HTTP based, so you get firewall penetration, SSL encryption if you need it, and a wealth of tools that know how to work both the client and server ends of the HTTP protocol.

As you might expect, XML-RPC isn’t the only implementation of this idea. Others include Allaire’s web Distributed Data Exchange (WDDX, http://www.wddx.org) and webMethod’s Web Interface Definition Language (WIDL, http://www.w3.org/TR/NOTE-widl).

Like XML-RPC, WDDX defines an XML-formatted request/response protocol. The WDDX SDK includes libraries that enable COM, Java, JavaScript, VBScript, Perl, and Cold Fusion applications to serialize complex data structures as WDDX packets and to exchange such packets. This means, for example, that you can take a server-based Cold Fusion array, serialize it as XML, send it to a browser, and unpack it as a VBScript array object used in a browser-based script.

Using webMethod’s WIDL, you can encapsulate existing CGI-style services, such as AltaVista’s, in an XML interface. The company’s B2B Integration Server (see http://www.webmethods.com/) uses this technique to create XML-based proxies that wrap clean, consistent, and stable XML packaging around CGI services that are messy, inconsistent, and ever-changing.

What’s the downside to this approach? The XML-RPC technique can complement, but not yet replace, standard CGI techniques. When you serve up an HTML form to a browser, it’s still going to respond using a conventional HTTP GET or POST, not an XML-RPC packet. Until the forms mechanism built into standard browsers becomes XML-aware, browser-driven groupware applications will still need to support a conventional HTML forms interface, at least on the input side. In terms of output, though, you’re free to intermix HTML for consumption by humans and XML for consumption by robots.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.118.95