What is XML-RPC?

It's a spec and a set of implementations that allow software running on disparate operating systems, running in different environments to make procedure calls over the Internet.

It's remote procedure calling using HTTP as the transport and XML as the encoding. XML-RPC is designed to be as simple as possible, while allowing complex data structures to be transmitted, processed and returned.

JavaScript implementation

Starting in 2019, there's a new implementation of XML-RPC in JavaScript.

Example client

Here's code that makes a simple XML-RPC call in a Node.js app.

const xmlrpc = require ("davexmlrpc");

const urlEndpoint = "http://betty.userland.com/rpc2";
const verb = "examples.getStateName";
const params = [5]; //an array containing one element, the number 5
const format = "xml"; //could also be "json"

xmlrpc.client (urlEndpoint, verb, params, format, function (err, data) {
    if (err) {
        console.log ("err.message == " + err.message);
        }
    else {
        console.log (JSON.stringify (data));
        }
    });

It sends a call to the demo server, betty.userland.com.

The procedure it calls is "examples.getStateName," with a single parameter, the number 5.

The call will be made in XML (it could also use JSON if we know the server supports it).

When the server returns, the callback receives the standard Node error object in the first param, and if there was no error, the data returned through XML-RPC in the second parameter.

Example server

Here's the code for a simple XML-RPC server.

const xmlrpc = require ("davexmlrpc");

var config = {
    port: 1417,
    xmlRpcPath: "/rpc2"
    }

xmlrpc.startServerOverHttp (config, function (request) {
    switch (request.verb) {
        case "uppercase":
            if (request.params.length > 0) {
                request.returnVal (undefined, request.params [0].toUpperCase ());
                }
            else {
                request.returnVal ({message: "There must be at least one parameter."});
                }
            return (true); //we handled it
        }
    return (false); //we didn't handle it
    });

Here's pseudo-code that calls this service. It returns THIS IS A TEST.

["xmlrpc://localhost:1417/rpc2"].uppercase ("this is a test")

Simple XML-RPC debugger

I've put up a simple app that lets you try calling an XML-RPC procedure from an HTML form, where you supply the URL of the endpoint, the verb you want to call, and its parameters as a JavaScript expression.

It then displays the result in JSON in a box below.

If there's an error message it's displayed in red.

You can try calling these routines on betty.scripting.com (it's the default endpoint):

  1. examples.getStateName, params = 31

  2. examples.getStateNames, params = [12, 22, 32, 42]

  3. examples.getStateList, params = [[12, 22, 32, 42]]

  4. examples.getStateStruct, params = [{state1: 3, state2: 42}]

  5. examples.getStateName, params = 900 (error)

  6. noSuchName (error)

If you open the JavaScript console, you'll see the actual XML-RPC cals, in XML, as they go over the wire. Screen shot.

How params work in the xmlRpcClient

The third param to the xmlRpcClient function is either a value or a list of values.

If it's a value, the XML-RPC procedure is called with a single parameter.

If it's a list with N elements, the procedure is called with N params.

If you want to call a procedure with a single param that's a list, send a list with a single element that's the list. It's the one weird case for this calling convention, and is illustrated with the third call, above.

Using JSON in place of XML

The XML-RPC standard specifies using XML, of course, but in this implementation, as an experiment, you can also use JSON.

When processing a request, we look at the first non-whitespace character. If it's a left curly brace, we treat it as JSON, not XML.

I haven't written a spec for the JSONified version, but I have created a cribsheet with examples that I used to guide the implementation.

Two types, <base64> and <dateTime.iso8601> are represented as strings. There is no way for the toolkit to know they are binary data or dates. This means that the XML and JSON versions are not exactly the same. Not sure what the implications of this will be. I wrote up the issue on Scripting News.

Please help test for interop

If you're running XML-RPC in your world, could you try testing against the server

I have running at betty.scripting.com. The server is accessible through port 80. The calls it handles are exactly the ones handled by the userland version of the test server. Demo code that calls the actual server is provided, in JavaScript.

The goal is to replace betty.userland.com with the one running here. But only after enough testing to be confident that it makes a good reference server.

If you have success, or find problems, please post a note in the issues section here. Thanks!

How to participate

I started a page at reboot.xmlrpc.com with links to new stuff related to this work.

Read Eric Kidd's fantastic XML-RPC HowTo.

Test your implementation on the XML-RPC Validator page.

The original site

The original site, dating back to 1998, is preserved.

Lest anyone forget

The first implementation of XML-RPC was in Frontier, in April 1998.

Questions, comments?

Post an issue here.