1

I have a Jersey REST services and I am looking for versioning to support the backward compatibility.

I have chosen the "Content Negotiation" option as changing the URLs was a difficult option for me. Service version is added in headers and identified in server side. A few services are having request payload and others are not.

I am not sure how we can implement the versioning for the services with request payload. Jersey maps the request payload object automatically and parses it. If I need to have two different versions (with version is identified in headers), how we do have handle the two request payloads and route them to the correct version of service?

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
Vict
  • 11
  • 2
  • Possible duplicate of [this question](http://stackoverflow.com/questions/4924034/easy-rest-resource-versioning-in-jax-rs-based-implementations) – lrnzcig Oct 31 '15 at 10:42
  • No, This question is not a duplicate. Other question and answers doesn't talk about the handling of request payloads. Infact none of the similar questions in Stackoverflow. – Vict Nov 20 '15 at 06:30

2 Answers2

0

Your methods' signatures will tell Jersey how you watn it to marshal the request input.

With Accepts-header content negotiation and Content-type-header content-negotiation together, compare:

@POST    
@Produces("application/vnd.dis-feed-v2+json")
@Consumes("text/csv")
@Path("/wiGGits")
public String postEnrollmentsV2(String payload) 

vs

@POST    
@Produces("application/vnd.dis-feed-v1+json")
@Consumes("text/xml")
@Path("/wiGGits")
public String postEnrollmentsV1(Document payload)

Jersey will generate a 400 error in the v1 of this /wiGGits service if the payload cannot be marshalled into xml.

If the content types are the same, and you want to reject versions of objects that do not match the expected version, you could also check the contents of the object for version differences

Rondo
  • 3,458
  • 28
  • 26
0

Just adding my two cents. The JAX-RS 2.0 specification (which Jersey implements) is very clear about how the request matching works:

3.7.2 Request Matching

A request is matched to the corresponding resource method or sub-resource method by comparing the normalized request URI, the media type of any request entity, and the requested response entity format to the metadata annotations on the resource classes and their methods. If no matching resource method or sub-resource method can be found then an appropriate error response is returned. [...]

Besides the NotFoundException (404 status) generated when no matching resources (classes and methods) can be found, the appropriate error response include (quoting the JAX-RS 2.0 specification again):

  • If no methods support the request method an implementation MUST generate a NotAllowedException (405 status) and no entity.

  • If no methods support the media type of the request entity body an implementation MUST generate a NotSupportedException (415 status) and no entity.

  • If no methods support one of the acceptable response entity body media types an implementation MUST generate a NotAcceptableException (406 status) and no entity.

Summarizing, you'll receive the appropriate error message when the request doesn't match your resources.


If you need, you can create a pre-matching filter, which is executed before the request matching is started. This filter allows you to modify the request. You can easily change the requested method, the requested URI and the requested headers.

To do it, just implement ContainerRequestFilter and annotate it with @PreMatching:

@Provider
@PreMatching
public class PreMatchingFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
         // Use the requestContext to modify the request
    }
}

For more details, have a look at the ContainerRequestContext API.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359