Create and link XSD to a WADL

oligofren picture oligofren · May 29, 2011 · Viewed 7.9k times · Source

I am creating some services using JAX-RS that need to take in arbitrarily complex objects as arguments, not just primitives like integers and strings. A discussion on the CXF mailing list says to just use a wrapper object as a single parameter in this case.

My concern is how to document the input format to the service? If creating a service that looks something like the following:

@POST
@Produces("application/json")
@Consumes("application/json")
@Path("oneParam")
public ComplexObject2 myServiceMethod(ComplexObject1 obj) {
    Foo f = obj.foo
    Bar b = obj.bar
    ...
}

the auto-generated WADL that CXF produces will only produce the following:

<resource path="/oneParam">
   <method name="POST">
      <request>
            <representation mediaType="application/json"/>
      </request>
      <response>
             <representation mediaType="application/json"/>
       </response>
   </method>
</resource> 

This contains no information on what the request or response actually contains. Sergey on the CXF mailing list said it was possible to link a schema to the representation, but how am I supposed to do that? And how do I create the XSD?

(P.S. Using POST for idempotent resources might not be RESTful, but it's not important here as we are in essence doing RPC using Json. This is more or less a 1:1 clone of an existing SOAP based api.)

Answer

kwo picture kwo · Jun 25, 2011

It is possible to link an XSD file into a WADL file and then to reference an XML element in the representation for requests and responses. However, as it is XML schema it doesn't apply to JSON representations.

To link an XSD into a WADL file, create a grammars element at the top of the file before the main resources element.

<grammars>
    <include href="myapp.xsd"/>
</grammars>

Then add a reference to an XML element as follows (using a modified version of your example):

<resource path="/oneParam">
   <method name="POST">
      <request>
            <representation mediaType="application/xml" element="myapp:oneParamRequest" />
      </request>
      <response>
             <representation mediaType="application/xml" element="myapp:oneParamResponse" />
       </response>
   </method>
</resource>

The prefix myapp is defined in the XSD and can be used in the WADL file as well.

I don't know to to configure CXF to do this automatically. My experience with Jersey is similar and we use the generated WADL as a starting point for hand-editing later.