DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

REST-JSON Service Versioning – Simple approach

Senthil Balakrishnan user avatar by
Senthil Balakrishnan
·
Feb. 05, 13 · Interview
Like (0)
Save
Tweet
Share
13.71K Views

Join the DZone community and get the full member experience.

Join For Free

Problem Statement:

As a provider of a service, one is obliged to maintain different versions of a service. One of the possible reasons could be the existing consumers of the service doesn’t want to upgrade to newer version.

Given the above problem statement, the service provider would need to manage & maintain multiple execution path, Request & Response structure / objects.

Note: I have chosen Spring MVC + Jackson Library as software stack for the solution approach.

Ex:

1.  Service that returns an employee object, given an employee Id.

@RequestMapping(value="/employee/{id}", method=RequestMethod.GET)
public ResponseEntity<Employee> fetchEmployee(@PathVariable int id){

   //Business operation/search & employee object is responded

   return new ResponseEntity<Employee>(new Employee(), HttpStatus.OK);
}

2.  The Employee response object could look something like this,


public class Employee { private int employeeId; private String name; private long primaryNumber; public int getEmployeeId() { return employeeId; } public String getName() { return name; } public long getPrimaryNumber() { return primaryNumber; } setters... }

3.  Assume the above service (/employee/{id}) is of version 1.0 & you are expected to add a secondary number as part of the employee response object only for a specific set of consumers. This would mean the service will have two version (1.0 & 2.0) 1.0 without secondary number & 2.0 with secondary number part of the response.

4.  Typical nature of implementation is write another service & expose that to the new consumer, this would also mean duplication of request/response objects in this case employee class.

Solution:

Based on the problem statement the solution proposed below would introduce a seamless versioning of your REST services on JSON.

I have introduced a new type of annotation to indicate all the supported versions of a REST Service.

@Version(versions="1.0,2.0,3.0...")

1.  Service that needs to be version aware, will be annotated with the custom annotation as show below.

@RequestMapping(value="/employee/{id}", method=RequestMethod.GET)
@Version(versions="1.0,2.0")
public ResponseEntity<Employee> fetchEmployee(@PathVariable int id){

	//Business operation/search employee object is responded

        return new ResponseEntity<Employee>(new Employee(), HttpStatus.OK);
}

2.  It’s just one part of it, how to control the request/response object, by version?

I have introduced a custom annotation @Include & @Exclude, to indicate if a property in the JSON object needs to be included


@Include (versions="1.0,..") - Include property for given versions of the service
@Exclude (versions="1.0,..") - Exclude property for given versions of the service

public class Employee {

private int employeeId;
private String name;
private long primaryNumber;
private long secondaryNUmber;

	@Include (versions="2.0")
	public long getSecondaryNUmber () {
		return secondaryNUmber;
	}

	
	public int getEmployeeId() {
		return employeeId;
	}

	public String getName() {
		return name;
	}

	public long getPrimaryNumber() {
		return primaryNumber;
	}
	
}

3.  Part of the solution is to overwrite JsonSerialize & JsonDeserialize to read the appropriate tags above to interpret the versions & form the request / response.

4.  Now Consumer has the responsibility to communicate the version of interest, which will be passed as request header attribute “version:1.0” or “version:2.0” etc.

Conclusion:

I have a working solution that I am thinking of open sourcing in a week or two, this article is more to get a feedback on the problem statement & your thoughts on my solution approach.

PS:

1.  Similar approach can be used for REST service on XML (with java Bindings) with some overwrites on XML serialize & de-serialize.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Playwright vs. Cypress: The King Is Dead, Long Live the King?
  • Easy Smart Contract Debugging With Truffle’s Console.log
  • Secrets Management
  • Handling Automatic ID Generation in PostgreSQL With Node.js and Sequelize

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: