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 fetchEmployee(
@PathVariable
int
id){
//Business operation/search & employee object is responded
return
new
ResponseEntity(
new
Employee(), HttpStatus.OK);
}
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...
}
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..."
)
@RequestMapping
(value=
"/employee/{id}"
, method=RequestMethod.GET)
@Version
(versions=
"1.0,2.0"
)
public
ResponseEntity
fetchEmployee( @PathVariable
int
id){
//Business operation/search employee object is responded
return
new
ResponseEntity
( new
Employee(), HttpStatus.OK);
}
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;
}
}
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:
Similar approach can be used for REST service on XML (with java Bindings) with some overwrites on XML serialize & de-serialize.
No comments:
Post a Comment