users@jersey.java.net

Resource and XML Schema versioning...

From: Rabick, Mark A (MS) <"Rabick,>
Date: Tue, 24 Feb 2009 09:08:52 -0600

Paul/Craig,

Thanks for the great suggestions:

>Once you have the media types it is possible if you wish to support
>URI-based content negotiation if the client cannot send an accept
>header.

>JAX-RS has support for resolving JAXBContext for media type and Java
>type. See the ContextResolver [1].

>Thus you could do:

> @Provider
> @Produces("application/foo-v1")
> public class Verson1ContextResolver implements
ContextResolver<JAXBContext> {
> public JAXBContext getContext(java.lang.Class<?> type) {
> ...
> }
> }


>I am not sure of the exact details of supporting two different
>serializations from the same object. IMHO it seems, without
>understanding too much about your use-case, easier to keep new and old
>versions separate (different packages). That way you do not have to
>work out backwards dependencies, plus think about the case when you
>require 3 versions etc.

As far as the URI-based content negotiation, are you suggesting I could couple the URI 'versioning' (../v1/...) in addition to custom/specific media types when the client can't send an "Accept: application/foo-vi?

Second, the generated application.wadl just indicates on methods that return application/xml:

<response>
    <representation mediaType="application/xml"/>
</response>

How can I get the JAXB context to genarate an XSD for each schema (v1,v2) and get the wadl to include corresponding XSD in the generated response element in the wadl?

>I am not sure of the exact details of supporting two different
>serializations from the same object. IMHO it seems, without
>understanding too much about your use-case, easier to keep new and old
>versions separate (different packages).

Unfortunately, I don't have specific use-case scenarios yet, just a requirement to preserve backward compatibility for legacy service clients... even though we don't have any 'legacy' clients yet (no actual clients yet), so I'm trying to at least architect my service framework to better support that in the future. The short of if is that I have 1 set of persistence objects (entity beans) at any given time in the most recent version. If I embed JAXB (javax.xml.bind) annotations in those persistence objects, lets just focus on 1 right now (Foo.java). If it has an attribute:

@XmlElement(required=true) protected String fooName; (v1)

<ns2:foo>
...
  <fooName>Name</fooName>
...
</ns2:foo>

A simple case might be a change to:

@XmlElement(required=true) protected String fooFullName; (v2)

<ns2:foo>
...
  <fooFullName>Name</fooFullName>
...
</ns2:foo>

At deployment time, I only have the (v2) annotated Foo.java, but I need to support clients that could ask for v1 schema bound Foo objects. The XmlElement annotation processing would use the attribute's name as the xml element. That was my question about an external JAXB configuration? I need the Foo.java to talk to our hibernate JPA based DAOs and that is the object that I get returned from our JPA/DB calls. I would need to produce output in foo-v1.xsd AND foo-v2.xsd. Would you recommend a 'transfer object' pattern and based on URI and accept header negotiation, keep multiple versions of Foo for use by Jersey? That is, I would have to write a façade of sorts to map the incoming foo-v1.xsd requests to Foo.java and then back from Foo.java to foo-v2.xsd with annotated FooV1.java and FooV2.java classes that reflect the different 'versions' of Foo?

Thanks again for all of your hard work and prompt responses!

--mark

_______________________________________________
Mark A. Rabick
Software Engineer
Em: mark.rabick_at_ngc.com