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.)