no mistake, XML-RPC has its flaws, but this function invocation
protocol is also well-suited to a variety of tasks. Here, columnist
David Mertz examines XML-RPC as a way of modeling object data, and --
in response to reader feedback -- compares XML-RPC as a means of
serializing objects with the
xml_pickle module discussed in his earlier columns. Code samples illustrate this comparison in detail.
is a remote function invocation protocol with a great virtue: It is
worse than all of its competitors. Compared to Java RMI or CORBA or
COM, XML-RPC is impoverished in the type of data it can transmit and
obese in its message size. XML-RPC abuses the HTTP protocol to
circumvent firewalls that exist for good reasons, and as a consequence
transmits messages lacking statefulness and incurs channel bottlenecks.
Compared to SOAP, XML-RPC lacks both important security mechanisms and
a robust object model. As a data representation, XML-RPC is slow,
cumbersome, and incomplete compared to native programming language
mechanisms like Java's
Data::Dumper, or similar modules for Ruby, Lisp, PHP, and many other languages.
In other words, XML-RPC is the perfect embodiment of Richard Gabriel's "worse-is-better" philosophy of software design (see Resources). I can hardly write more glowingly on XML-RPC than I did in the previous paragraph, and I think the protocol is a perfect match for a huge variety of tasks. To understand why, it's worth quoting the tenets of Gabriel's "worse-is-better" philosophy:
- Simplicity: The design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design.
- Correctness: The design must be correct in all observable aspects. It is slightly better to be simple than correct.
- Consistency: The design must not be overly inconsistent. Consistency can be sacrificed for simplicity in some cases, but it is better to drop those parts of the design that deal with less common circumstances than to introduce either implementational complexity or inconsistency.
- Completeness: The design must cover as many important situations as is practical. All reasonably expected cases should be covered. Completeness can be sacrificed in favor of any other quality. In fact, completeness must sacrificed whenever implementation simplicity is jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained; especially worthless is consistency of interface.
Writing years before the specific technology existed, Gabriel identifies the virtues of XML-RPC perfectly.
xml_pickle or XML-RPC?
I have written a moderately popular module for Python called
xml_pickle. The purpose of this module (discussed previously in this column, see Resources) is to serialize Python objects, using an interface that's mostly the same as those of the standard
pickle modules. The only difference is that in my module, the representation is in XML. My intention all along with
was to create a very lightweight format that could also be read from
other programming languages (and across Python versions). A DTD
accompanies the module for users who want to validate XML pickles, but
feedback from users has suggested that formal validation is rarely a
A recurrent question I have received from users of
is whether XML-RPC would be a better choice, given its more widespread
use and existing implementations in many programming languages. While
the answer to the narrow question probably favors
xml_pickle, the comparison is worthwhile -- and it raises some points about data-type richness.
On first pass, XML-RPC seems to do something different from
XML-RPC calls remote procedures and gets results back. The typical
usage example in Listing 1 appears at the XML-RPC Web site and in the Programming Web Services with XML-RPC book (see Resources):
creates string representations of local in-memory objects. These may not
seem the same, but in order to call a remote procedure, XML-RPC first
needs to convert its arguments to suitable XML representations (in
other words, pickle/serialize the parameters). Similarly, a return
value from an XML-RPC call can contain a nested data structure.
.dumps() method of the
xmlrpclib shares its name with an
module (both inspired by several standard modules), and does the same
thing -- writes the XML serialization without performing an actual call.
On first examination,
appear to be functionally interchangeable, at least if one only cares
about the serialization aspect. But as we will see, a closer look
reveals some differences.