Menu

Backends Sharing Data

August 11, 1999

Edd Dumbill


Scripting languages have been in use for years to make function calls and to integrate disparate applications. A little bit of script glue can make applications from different vendors talk to each other and exchange information.

Ever wished you could do that for web sites? Well, now you can. XML-RPC is a very simple protocol for performing remote procedure calls over HTTP. It was designed by Userland Software, working with Microsoft.

As some web sites become more like online applications, the advantages of offering a programmable API into their services are obvious. You've almost certainly already got a Hotmail account, or equivalent. Do you store your schedule on a web-based service? One of the more common frustrations with this kind of applications is that there's poor integration with your personal computer. If these online applications exposed XML-RPC APIs, you could write scripts to access your data and perform functions from these sites — all from your machine.

The scope for inter-operation between web sites is large. All that's needed is a standard, language-neutral way of communicating. There are already ways and means of inter-operation: CORBA, DCOM and so on, but XML-RPC offers a different, more lightweight, option.

Protocol overview

XML-RPC's simplicity is also its strength. It defines the bare minimum needed to get procedure calls working. Although this may not appeal to those who enjoy the rigor of thorough specifications, it has enabled rapid implementation of XML-RPC in a variety of languages, including Python, Java, Perl, Tcl, ASP, and PHP3.

The protocol is based around a single HTTP POST containing a request payload, and the corresponding response containing the result payload. The request payload contains a method name and a list of parameter values. Fundamental types supported are string, integer, floats, dates, binary (via base 64 encoding), and booleans. Composite data types can be passed using the array and struct tags.

The response must contain exactly one return value, or an error condition. The limitation to a single value isn't a great burden, as composite types can be used to express multiple values.

The request

A typical XML-RPC HTTP request for asking a web email service how many new messages you have might look like this:


  POST /xmlrpcInterface HTTP/1.0

  User-Agent: Yoyodyne XML-RPC Client 1.0

  Host: xmlrpc.emailservice.com

  Content-type: text/xml

  Content-length: 195



  <?xml version="1.0"?>

  <methodCall>

    <methodName>email.getNumberNewMessages</methodName>

    <params>

      <param><value><string>myUserName</string></value></param>

    </params>

  </methodCall>

This is the XML-RPC be the equivalent of a local function call looking something like this:


   email.getNumberNewMessages("myUserName");

For simplicity here, I've omitted any authentication. XML-RPC makes no attempt to specify any authentication or encryption measures: you could use those normally available with HTTP or invent your own to be used within the request body.

The URI specified on the first line is arbitrary and is chosen by the server implementor. Unlimited XML-RPC servers could be run on one web site, as long as they have distinct URIs. An XML-RPC interface is unambiguously described by its full URL (including port number, to be really exact). The HTTP headers shown are all mandatory in an XML-RPC request.

Fortunately, most of these mechanics are hidden in the actual implementations. In general, the richness of the language in use dictates how tightly the XML-RPC protocol is bound into the language. For comparison, here are two invocations of the above method, one in Java, the second using PHP.


  // Java example

  XmlRpcClient xmlrpc=new XmlRpcClient

    ("http://xmlrpc.emailservice.com:80/xmlrpcInterface");

  Vector params=new Vector();

  params.addElement("myUserName");

  Integer result=(Integer)xmlrpc.execute

    ("email.getNumberNewMessages", params);



  // PHP example

  $client=new xmlrpc_client("/xmlrpcInterface",

     "xmlrpc.emailservice.com", 80);

  $resp=$client->send(new xmlrpcmsg("email.getNumberNewMessages",

     array(new xmlrpcval("myUsername", "string"))));

  $val=$resp->value();

  $result=$val->scalarval();

The response

Here is an example response to the above hypothetical request:


  HTTP/1.1 200 OK

  Connection: close

  Content-Length: 148

  content-Type: text/xml

  Date: Wed, Jul 28 1999 15:59:04 GMT

  Server: Yoyodyne XML-RPC Server 1.0



  <?xml version="1.0"?>

  <methodResponse>

    <params>

      <param>

        <value><int>10</int></value>

      </param>

    </params>

  </methodResponse>

Exactly one <param> is always returned. If a fault occurred, a request body similar to the following will be returned:


  <?xml version="1.0"?>

  <methodResponse>

    <fault>

      <value>

        <struct>

          <member>

             <name>faultCode</name>

             <value><int>23</int></value>

          </member>

          <member>

             <name>faultString</name>

             <value><string>Unknown username</string></value>

          </member>

        </struct>

      </value>

    </fault>

  </methodResponse>

Constructing XML-RPC servers is quite simple. You just need to provide a function in your chosen language that provides the functionality required, and instruct the XML-RPC server classes of its existence. Here's an example of "Hello, World" using an XML-RPC implementation for ASP:


  <!--#include file="xmlrpc.asp" -->

  <%

  rpcserver



  function helloWorld()

       helloWorld = ("Hello, World")

  end function

  %>

And, to contrast, an implementation in PHP:


  <?php

  include("xmlrpc.inc"); include("xmlrpcs.inc"); 



  function helloWorldImpl($params) {

  return new xmlrpcresp(new xmlrpcval

      ("Hello, World", "string"));

  }



  $s=new xmlrpc_server(array("helloWorld" => "helloWorldImpl"));

  ?>

Using XML-RPC

Implementations of both client and server are currently available for popular language platforms: these are in varying stages of maturity. An up-to-date list can be found at the XML-RPC home page. Most of the implementation distributions are freely available and include examples. The open-source application server Zope has XML-RPC facilities, as does Userland Software's Frontier content management tool.

XML-RPC is proving a useful way to tie together systems written in different languages on different operating systems, and enabling them to co-operate. The real advantage is that the structure of XML-RPC is flexible enough to be put to many different applications.

There are many possible uses for XML-RPC both inside and outside of the firewall. The potential is limited only by the imagination. I want to be able to build that integrated tool which will filter information from my schedule, email, stock portfolio and the weather, and download it all into my PDA, at the same time as uploading all my email and calendar events I entered while offline. If web application providers embrace XML-RPC, this could become a reality. It could go further, as scripters use the ability to combine features from web sites which have no pre-arranged inter-operation.

There are also possibilities for XML-RPC in micro-payment-funded services offering functionality or content. This is important, since widespread use of XML-RPC may only happen if there's a reward for the party offering the XML-RPC service. Clearly, in such a protocol advertising isn't feasible, so there needs to be a tie-in with purchasing in order to get a return.

Particularly encouraging is the arrangement for co-operation via XML-RPC between Frontier and Zope. If this kind of collaboration continues, it can only be good for the web developer. Web authoring tools, and software tools in general, could implement XML-RPC calls to expand their feature set. For example, it would be great if you could link together your web authoring tool with online HTML validators and tune-up services.

However, there is still some way to go for XML-RPC to become a robust enough standard for widespread adoption. Despite the simplicity of the specification being a strength (have you read the XSLT spec recently?), it needs some additions to promote better inter-operation and clear up some ambiguity. The most pressing of these is the need to add introspection facilities, so tools can automatically discover which methods a server provides and what parameters are required. Work is currently ongoing among the XML-RPC server developers on such recommendations.