JSON-Schema in WADL
In between other jobs I have been recently been reviewing the WADL specification with a view to fixing some documentation problems with a view to producing an updated version. One of the things that because apparent was the lack of any grammar support for languages other than XML – yes you can use a mapping from JSON<->XML Schema but this would be less than pleasant for a JSON purist.
So I began to look at how one would go about attaching a JSON-Schema grammar of a JSON document in a WADL description of a service. This isn’t a specification yet; but a proposal of how it might work consistently.
Now I work with Jersey mostly, so lets consider what Jersey will current generate for a service that returns both XML and JSON. So the service here is implemented using the JAX-B binding so they both use a similar structure as defined by the XML-Schema reference by the include.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <application xmlns="http://wadl.dev.java.net/2009/02"> <doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 1.16-SNAPSHOT 10/26/2012 09:28 AM"/> <grammars> <include href="xsd0.xsd"> <doc title="Generated" xml:lang="en"/> </include> </grammars> <resources base="http://localhost/"> <resource path="/root"> <method id="hello" name="PUT"> <request> <representation xmlns:m="urn:message" element="m:requestMessage" mediaType="application/json" /> <representation xmlns:m="urn:message" element="m:requestMessage" mediaType="application/xml" /> </request> <response> <representation xmlns:m="urn:message" element="m:responseMessage" mediaType="application/json"/> <representation xmlns:m="urn:message" element="m:responseMessage" mediaType="application/xml" /> </response> </method> </resource> </resources> </application>
So the first thing we considered was re-using the existing element property, which is defined as a QName, on the representation element to reference an imported JSON-Schema. It is shown here both with and another an arbitrary namespace to it can be told apart from XML elements without a namespace.
<grammars> <include href="xsd0.xsd" /> <include href="application.wadl/responseMessage" /> </grammars> <representation element="responseMessage" mediaType="application/json"/> Or xmlns:json="http://wadl.dev.java.net/2009/02/json" <representation element="json:responseMessage" mediaType="application/json" />
The problem is that the JSON-Schema specification as it stands doesn’t have a concept of a “name” property, so each JSON-Schema is uniquely identified by it’s URI. Also from my read of the specification each JSON-Schema contains the definition for at most one document – not the multiple types / documents that can be contained in XML-Schema.
So the next best suggestion would be to just use the “filename” part of the URI as a proxy for the URI; but of course that won’t necessarily be unique. I could see for example the US government and Yahoo both publishing there own “address” micro format.
The better solution to this problem is to introduce a new attribute, luckily the WADL spec was designed with this in mind, that is of type URI that can be used to directly reference the JSON-Schema definitions. So rather than the direct import in the previous example we have a URI property on the element itself. The “describedby” attribute name comes from the JSON-Schema proposal and is consistent with the rel used on atom links in the spec.
xmlns:json="http://wadl.dev.java.net/2009/02/json-schema" xmlns:m="urn:message" <grammars> <include href="xsd0.xsd" /> </grammars> <representation mediaType="application/json" element="m:responseMessage" json:describedby="application.wadl/responseMessage" />
The has the secondary advantage in that this format is backwardly compatible with tooling that was relying on the XML-Schema grammar. Although this is probably only of interesting to people who work in tooling / testing tools like myself.
Once you have the JSON-Schema definition then some users are going to want to do away with the XML all together, so finally here is a simple mapping of the WADL to a JSON document that contains just the JSON-Schema information. It has been suggested by Sergey Breyozkin the JSON mapping would only show the json grammars and I am coming around to that way of thinking. I would be interested to hear of a usecase for the JSON mapping that would want access to the XML Schema.
{ "doc":{ "@generatedBy":"Jersey: 1.16-SNAPSHOT 10/26/2012 09:28 AM" }, "resources":{ "@base":"http://localhost/", "resource":{ "@path":"/root", "method":{ "@id":"hello", "@name":"PUT", "request":{ "representation":[ { "@mediaType":"application/json", "@describedby":"application.wadl/requestMessage" } ] }, "response":{ "representation":[ { "@mediaType":"application/json", "@describedby":"application.wadl/responseMessage" } ] } } } } }
I am currently using the mime type of “application/vnd.sun.wadl+json” for this mapping to be consistent with the default WADL mime type. I suspect we would want to change this in the future; but it will do for starters.
So this is all very interesting but you can’t play with it unless you have an example implementation. I have something working for both the server side and for a Java client generator in Jersey and wadl2java respectively and that will be the topic of my next post. I have been working with Pavel Bucek on the Jersey team on these implementations and the WADL proposal, thanks very much to him for putting up with me.