Regurgitating an old rant (Encoding, XForms, and SOAP/XML-RPC): "

I ran into two work-related problems today that left me feeling like there are some aspects of two very recent (Web 2.0-esque if we wish to join the buzzword orgy of late) architectures (REST/Services and XForms) that are problematic:

Demonstrating an Achilles Heel Of XML Messaging

XML as a medium for remote communication (evangelized more with WSDL-related architectures than in REST) has over-stated its usefullness in at least one concrete regard, in my estimation. I've had a hard time taking most of the architectural arguments on the pros/cons of SOAP/XML-RPC versus REST seriously because it seems to be nothing more than buzzword warfare. However, I recently came across a concrete, real world example of the pitfalls of implementing certain remote service needs on XML-based communication mediums (such as SOAP/XML-RPC).

If the objects/resources you wish to manipulate at the service endpoints are run of the mill (consider the standard cliche purchase order example(s)) then the benefits of communicating in XML is obvious: portability, machine readability, extensibility, etc.. However consider the scenario (which I face) in which the objects/resources you wish to manipulate are XML documents themselves! This scenario seems to work to the disadvantage of the communication architecture.

Lets say you have a repository at one end (which I do) that has XML documents you wish to manipulate remotely. How do you update the documents? I've discussed this before (see: Base64 encoded XML content from an XForm) so I'll spare the details of the problem. However, I will mention that in retrospect this particular problem further emphasizes the advantage of a MinimalistRemoteProcedureCall (MRPC) approach - MRPC is my alternative acronym for REST :).

Consider the setContent message:

[SOAP:Envelope]
    [SOAP:Body]
     [foo:setContent]
       [path] .. path to document [/path]
       [src]... new document as a fragment ...[/src]
     [/foo:setContent]
   [/SOAP:Body]
[/SOAP:Envelope]

Notice that the location of the resource we wish to update is embedded within the message transmitted (via SOAP), which is transported on top of another communication medium (HTTP) that already has the neccessary semantics for saying the same thing:

Set the content of the resource identified by a path

In the SOAP scenario, the above message is delivered to a single service endpoint (which serves as an external gateway for all SOAP messages) which has to then parse the entire XML message in order to determine the method invoked (setContent in this case) and the parameters passed to it (both of which are only header information on a document that consists mostly of the new document).

However, in the MRPC scenario this service would be invoked simply as an HTTP PUT request sent directly to the XML document we wish to update:

Method: PUT
Protocol:  HTTP/1.0
URI: http://remoteHost:port/< .. path to XML document ..>
CONTENT:
... new document in it's entirety ..

Here, there is no need for a service middleman to interpret the service requested (and no need to parse a large XML document that contains another document embedded as a fragment). The HTTP request by itself specifies everything we need and does it using HTTP alone as the communication medium. This is even more advantageous when the endpoint is a repository that has a very well defined URI scheme or general addressing mechanism for it's resources (which 4Suite does, the repository in my case).

The Headaches of Base 64 Encoding in XForms

Since i didn't have the option of a REST-based service architecture (the preferred solution) I was relegated to having to base64 encode the new XML content and embed it within the XML message submitted to the service endpoint, like so:

[SOAP:Envelope]
   [SOAP:Body]
     [foo:setContent]
       [path] .. path to document [/path]
       [src]... base64 encoding of new document's serialization ...[/src]
     [/foo:setContent]
   [/SOAP:Body]
[/SOAP:Envelope]

Base 64 seemed like the obvious encoding mechanism mostly because it would seem from an interpretation of the XForms specification that due to the data binding restrictions of the Upload Control when bound to instances of type xsd:base64Binary a conforming XForms processor is responsible for having the capability to encode to Base 64 on the fly. Now, this is fine and dandy if the XML content you wish to submit is retrieved from a file on the local file system of the client communicating remotely with the server. However, what if you wish to use an instance (a live DOM) as the source for the update? This seems like a very reasonable requirement given that one of the primary motivation of XForms is to encourage the use of XML instances as the user interface data model (providing a complete solution to the 'M' in the MVC architecture.)

However:

  • There is no mechanism within XForms for serialising live instances (there needs to be such a standard so implementations don't create their own proprietary mechanisms)
  • There is no mechanism within XForms for explicitely encoding text in some portable binary format (which is incredibly useful IMHO - as shown above)
"

(Via Uche Ogbuji.)