One of the main benefits of using XML-RPC is that the actual XML manipulation part is kept completely hidden from the client and server application code. Both the client and server application code only see native data as input and output. This makes life easier because using native data instead of XML helps keep your application code cleaner, easier to read, and more portable (especially across web browsers).
XML-RPC accomplishes this task by creating a small set of lowest common denominator data types that virtually every language can represent. This means that almost every language and runtime environement can convert between XML-RPC and it’s own native data types.
The following data types make up the exclusive set:
- dateTime iso8601 (considered worthless, though, because of no timezone format.)
- struct (container for key/value pairs)
- array (container of ordered elements)
It turns out that most meaningful data transmission can be represented in this way. Notice that XML-RPC’s data types are almost exactly the same as JSON. Only the DateTime and Base64 types are not represented directly in raw JSON.
The Anatomy of an XML-RPC Request
Here’s what happens on the client durring an XML-RPC request:
- The client passes the paramters for the request to the XML-RPC library as native data types and specifies a response handler function to recieve the return value of the request.
- The XML-RPC client library takes these these native parameters and serializes them into into an XML-RPC request document. The process of converting native data types into XML is called "marshalling".
- The client sends the XML-RPC request document to the server over HTTP
- When the response comes back, the client XML-RPC library "unmarshalls" the return value from XML into a native data type representation.
- The native return value is passed into the response handler function
As you can see, the client application code is kept completely unaware that any XML is being used at all. In fact, to the client it almost looks like a normal native function call that never leaves the client. The asynchronous nature of the request is the only thing that makes it slightly different from a normal call. Asynchronous response handlers do, however, look very similar to function calls on the client using documetn.setTimeout().
A similar process happens on the server:
- The server XML-RPC library recievies the XML-RPC request document from the client
- The server XML-RPC library extracts the name of the method to invoke and unmarshalls the XML encoded parameters into native data types.
- The server XML-RPC library invokes the specified method and passes in the native data type parameters
- The web service method is invoked and a native data value is returned.
- The server XML-RPC library marshalls the return value into XML and sends the response back to the client
Again, you can see that the server application logic has no idea that it was invoked from XML or that it’s return value will be sent to the client as XML. It’s inputs and outputs are the native data types of its environment.
This diagram, taken from XMLRPC.com illustrates the marshalling and unmarshalling of native data types into XML-RPC:
What Flickr Does Right and Wrong
So, the Flickr XML-RPC API gets the first part right: All of its methods accept XML-RPC Structs as input parameters. This is exactly right and very well done.
The part that Flickr gets slightly wrong are the return values. They return an XML document encoded as an XML-RPC string value. What makes this painful is that it requires the client code to directly use an XML DOM to access the data. As I’ve already stated, keeping XML manipulation out of the application is exactly what XML-RPC is about. It’s not that Flickr’s solution wont work, it’s just that it kind of defeats the purpose. For Flickr to do it right, they would need to return their repsonse data as pure XML-RPC data types.
My presentation in Maine on XMLRPC
technorati tags: xmlrpc, flickr