Note: XML-RPC is a legacy technology that predates modern web standards like REST and JSON. While it's largely considered outdated today, we include support and documentation for those maintaining or integrating with older systems that still rely on it.
Creating a XML-RPC web service is virtually identical to how you create a JSON-RPC web service. The difference between the XML-RPC and the JSON-RPC is the name.
The following example illustrates the differences:
-- Load the JSON-RPC stack local jsonrpc = require"jsonrpc" -- Load the XML-RPC stack local xmlrpc = require"xmlrpc" -- Create the JSON-RPC service local jsonService = jsonrpc.new("service name", serviceDescription) -- Create the XML-RPC service local xmlService = xmlrpc.new("service name", serviceDescription)
Just like the JSON-RPC stack parses the received JSON into Lua objects, the XML-RPC stack parses the received XML into identical Lua objects. The response is handled in a similar manner, the JSON-RPC stack automatically translates the response data to JSON and the XML-RPC stack automatically translates the response data to XML.
It is for this reason possible to use the same Lua service functions for serving as a XML-RPC service and as a JSON-RPC service. The following example extends the JSON-RPC directory service example to also serve as a XML-RPC service.
-- Load the JSON-RPC stack local jsonrpc = require"jsonrpc" -- Load the XML-RPC stack local xmlrpc = require"xmlrpc" -- The "add" JSON-RPC and XML-RPC service local function add(a,b) return a + b end -- The "subtract" JSON-RPC and XML-RPC service local function subtract(a,b) return a - b end -- The Service Description Object used by -- the JSON-RPC and XML-RPC constructors local serviceDescription = { math={ add=subtract, subtract=subtract, } } -- Create the JSON-RPC service local jsonService = jsonrpc.new("JSON-RPC service", serviceDescription) -- Create the XML-RPC service local xmlService = xmlrpc.new("XML-RPC service", serviceDescription) -- The directory callback function. -- Service JSON-RPC at relative path 'json-rpc' and -- XML-RPC at relative path 'xml-rpc' local function webservice(dir,func,path) if path == "json-rpc" then jsonService:execute(request, response) elseif path == "xml-rpc" then xmlService:execute(request, response) else -- No other services response:senderror(404) end end -- Create directory: "web-service" dir = ba.create.dir("web-service", webservice) ba.dirtop():insert(dir) -- Insert into first root directory
In the above example, the math service is made available at the following URLs:
JSON-RPC clients: http://localhost/web-service/json-rpc
XML-RPC clients: http://localhost/web-service/xml-rpc
Though JSON-RPC and XML-RPC provide similar capabilities, XML-RPC provides two types that cannot be represented in JSON. The two XML-RPC types dateTime.iso8601 and base64 requires special handling.
Time can be sent using ISO 8601 encoding. A limitation with the Barracuda XML-RPC stack is that time can only be represented as UNIX time, in other words time cannot be before January 1, 1970.
Receiving:
A dateTime.iso8601 encoded XML-RPC time is automatically converted to a number if the time is within the accepted UNIX time range. A date/time outside of the UNIX time range is returned as a string.
Sending:
You can explicitly tell the XML-RPC stack to return a UNIX time i.e. a number as dateTime.iso8601 encoding by calling xmlrpc.iso8601The following service function illustrates how to return iso8601 encoded data/time:
local function currentTimeService() return xmlrpc.iso8601(os.time()) end
B64 encoding is typically used when sending binary data. A string in Lua may contain any bytes and one can therefore store binary data in Lua strings.
Receiving:
When the XML-RPC stack receives B64 encoded data, the data is automatically converted to a Lua string.
Sending:
When the XML-RPC stack converts the response from a Lua XML-RPC service function to XML, strings are by default converted to the XML-RPC string type. The XML-RPC stack can send a Lua string as B64 encoded data, but you must explicitly tell the XML-RPC stack to do the conversion. The conversion is done by calling xmlrpc.base64
The following two service functions return response data as a XML-RPC string and as XML-RPC base64 encoded data respectively:
local function myService1() return "This is a string" end local function myService2() return xmlrpc.base64("This is a string encoded as B64") end