11 March, 2021
In this article, I'll talk about a pretty old RPC Protocol, XMLRPC. It is over 20 years old now and, it is mostly associated in legacy systems. I'd have never come across it if it wasn't for ROS. ROS 1.x still uses XMLRPC for all of its communication. So, I decided to read out the protocol specification.
I was surprised that the protocol is quite simple. It leverages the already existing Request-Response foundation of HTTP and defines the Message Types for Request and Response. That's pretty much it.
What is RPC?
RPC stands for Remote Procedure Call. Think of procedure call as a function invocation. So a remote procedure call is the function invocation done remotely where remotely can mean anything from a separate process on the same machine to a machine across the world.
In RPC's context, the caller is the RPC Client and, the callee is the RPC Server. An RPC client needs to figure out how to send the procedure name and its parameters to the RPC Server. The Server will then invoke the function and return the response. An RPC Protocol defines the way of encoding and sending the data across.
For transporting the data, XMLRPC relies on the HTTP Standard, thus eliminating most of the complexity. XMLRPC uses the
POST Method of HTTP for the Request, but it does not care about the URI. HTTP Server can use the URI for routing.
It does require the following HTTP Headers to be present.
- Content-Type (text/xml)
This one is a little more obvious. XMLRPC uses XML for encoding the data. It recognizes most of the primitive data types:
- Binary Bytes (Base64 Encoded)
Additionally, XMLRPC supports compound datatypes like Arrays and Custom Structs (that can also be recursive).
The Request must have a single
methodCall XML structure. There should be a single
methodName item under it. Method Name is the name of the remote procedure. All the parameters are defined under the
params array as
param items. The following snippet is a sample Request body.
<?xml version="1.0"?> <methodCall> <methodName>sum</methodName> <params> <param> <value><i4>41</i4></value> </param> <param> <value><i4>59</i4></value> </param> </params> </methodCall>
The Response must have a single
methodResponse XML structure. The structure can have either a
params item or a
params item is used for a successful procedure invocation. XMLRPC supports only a single return parameter. But it can be any supported datatype. The successful invocation would return a response similar to this.
<?xml version="1.0"?> <methodResponse> <params> <param> <value><i4>100</i4></value> </param> </params> </methodResponse>
On the other hand, the
fault item is used for a failed procedure invocation. The Fault response is defined as a struct with two fields,
failureString. A failed RPC call would look like this.
<?xml version="1.0"?> <methodResponse> <fault> <value> <struct> <member> <name>faultCode</name> <value><i4>-1</i4></value> </member> <member> <name>faultString</name> <value><string>Some error occurred</string></value> </member> </struct> </value> </fault> </methodResponse>
XMLRPC is a simple plain-text protocol that humans and machines can parse. However, it has its flaws. XML as a data encoding format is rapidly being replaced with JSON. The most commonly cited reason for that seems to be the complexity of XML. Moreover, XMLRPC's Request/Response structures are also criticized to be verbose and redundant.
Additionally, XMLRPC is a plain-text protocol. This is good because humans can easily understand communication, but it's not performant because computers do not understand it. Computers need to first parse the text to understand the data. More and more modern protocols are choosing binary format over plain-text including HTTP/2 and HTTP/3.
Some modern-day replacements are generally known to be better in some ways than XMLRPC. I plan to read the specifications of these Protocols and possibly cover them in future posts.