I'm struggling with a client-server project where I have Java apps out on the Internet that store data to a backend server. The format of this data is well-defined, but the project is constantly evolving, so the definition keeps changing! To cope with the change I defined a simple REST interface on the server that offers only key-value storage. Clients can store or retrieve a chunk of data by referencing a unique key. This is nice because I don't have to modify the server interface (or the backend database) when the data format changes. To the server, it's just a bunch of opaque blobs.
Of course, the issue then becomes, "What goes inside the blob?" For that I wrote an XML Schema that defines the content of a blob. At first it was great, since the Schema gives a bunch of nice things "for free": A formal yet human-readable spec of the file format, automatic validation of its contents, marshalling/unmarshalling to a stream, and auto-generated Java classes for programmatic access to the data.
But then change happened! The Schema had to be altered, and naturally I ran into forward- and backward-compatibility issues. To deal with the constantly changing Schema, I came up with a solution that embeds a version number into the XML namespace, and I apply a series of XSL Stylesheets to "upgrade" any given blob to the latest version. For example, I'm now on version 1.3 of my Schema, so when I unmarshal a blob, I run it through a 1.0-to-1.1 XSLT, then a 1.1-to-1.2 XSLT, and finally a 1.2-to-1.3 XSLT. This works, but it's not sustainable because the chain keeps getting longer, which lowers performance and sucks up memory, plus I have to keep writing new Stylesheets, which takes time and isn't fun.
Now here's the funny thing... In addition to the Java clients, the project also has iOS apps as clients, and iOS has none of the nice enterprise-y features associated with XML Schemas. There's no validation of the stream, no auto-generation of Objective-C classes, etc., just a low-level event-driven XML parser. But ironically I'm finding this so much easier! For example, if the XML gets a new element, I just add a new
if clause. If an element goes away, I remove its clause. Basically, I do a "best effort" at interpreting the XML stream, silently ignoring any unrecognized elements. I don't need to think about what version the file format is or whether it's valid. Plus this is much faster because there's no XSLT chaining, and it saves a lot of my time because I don't have to write any XSLT code.
So far this approach has worked out great, and I've not missed having an XML Schema on the iOS side. I'm now wondering if a Schema, despite its nice feature set, is totally the wrong technology for a file format that often changes. I'm thinking about ditching my XML Schema altogether and using the same "best effort" low-level approach in Java that I'm doing in iOS.
So is my negative assessment of XML Schemas correct? Or is there something I've missed? Perhaps I need to rethink the server interface? Or maybe I shouldn't have been using XML in the first place? I'm open to all suggestions. Thanks for reading!