XML-RPC Home Page
XML-RPC @ Wikipedia
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