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.