Implementing Versioning Support in Restful Web-Services

DZone 's Guide to

Implementing Versioning Support in Restful Web-Services

· Integration Zone ·
Free Resource

Versioning Restful Web-services:

For maintaing backward compatibilty, at times you may need to support multiple versions of restful web-service resources (here after refered to as resources). It may be desirable at that point to be able to have resources versioned at package, class or individual method level. Annotations come handy in fulfillinhg this need. Here is summary of the steps to add versioning support:

  • Create a custom Annotation:


@Target({ElementType.TYPE, ElementType.PACKAGE, ElementType.METHOD})

public @interface Versioned{

    String[] versions();


  • Annotate Resources:
@Versioned(versions = {"1.0","2.0"})
public class UserResource{…}
  • Finally create an interceptor that intercepts requests, checks if supported version is passed in Accept header (e.g. Accept: application/xml;ver=1.0) and returns response code 415 for unsupported versions (example uses JBoss jax-rs implementation):



public class VersionCheckInterceptor implements PreProcessInterceptor{

    private static final Pattern pattern = Pattern.compile("ver\\s*=\\s*([\\d]+.[\\d]+)");

    public static final String ALLOW_ALL = "ALLOW_ALL";



    public ServerResponse preProcess(HttpRequest httpRequest, ResourceMethod resourceMethod) throws Failure, WebApplicationException{

        Versioned methodAnnotation = resourceMethod.getMethod().getAnnotation(Versioned.class);

        if(methodAnnotation != null && methodAnnotation.versions() != null && ArrayUtils.contains(methodAnnotation.versions(), ALLOW_ALL))return null;

        Versioned classAnnotation = resourceMethod.getResourceClass().getAnnotation(Versioned.class);

        Versioned packageAnnotation = resourceMethod.getResourceClass().getPackage().getAnnotation(Versioned.class);

        Versioned annotation = methodAnnotation != null?methodAnnotation:(classAnnotation != null?classAnnotation:packageAnnotation);

        if(annotation == null) return null;

        List<String> acceptHeaders = httpRequest.getHttpHeaders().getRequestHeader("Accept");

        boolean reqContainsSupportedVersion = false;

        for(String version : acceptHeaders){

            Matcher matcher = pattern.matcher(version);

            if(!matcher.find()) continue;

            String versNum = matcher.group(1);

            if(versNum == null) continue;

            versionPasssed = true;

            if(ArrayUtils.contains(supportedVersions, versNum)){

                reqContainsSupportedVersion = true;




        if(!reqContainsSupportedVersion) throw new NotFoundException ();

        return null;




Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}