Reputation: 2002
In my spring controller, I have 2 rest api methods. example: getUser, getRole One client is accessing it by like "/api/v1". Now I want to update one of the methods. i.e., getRole. So the new method/version will be "/api/v2". But no change in methods of v1. i.e., "/api/v1".
How to handle the rest methods with both versions in the same project ? I mean, getUser rest API should support both "/api/v1" and "/api/v2". And getRole rest API should support both versions but different functionality (example: database changed, logic changed). In simple words, 1. getUser will have 1 method which supports both versions. 2. getRole will have 2 methods for each versions.
Please help me here.
Upvotes: 5
Views: 7614
Reputation: 1141
If you want to do use separate method for both version you can by defining different value in @RequestMapping
@RequestMapping(
value = "baseurl/v1/role",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
and
@RequestMapping(
value = "baseurl/v2/role",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
but if you want to handle it in same method you can using
@RequestMapping(
value = "baseurl/{version}/role",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public returnType methodName(@PathVariable("version") String version){
// code to check version
}
@RequestMapping(
value = "baseurl/role",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public returnType methodName(@RequestHeader("version") String version){
// code to check version
}
But as you said you have different version of api's prefer to manage them in separate controller using @RequestMapping
at class level
@RestController
@RequestMapping("/v1")
public class anyController {
}
and
@RestController
@RequestMapping("/v2")
public class anyController {
}
Upvotes: 6
Reputation: 5259
I would do the following approach
Define a version at the application level (Start with /v1) -- this version is changed only when you want to make bigger changes to your whole API and is usually stable.
Resources (roles, users) etc. should be versioned additionally using content negotiation via the headers
e.g.
GET /v1/users/503deb67-ff6e-4d1c-a225-408b910b7252/ HTTP/1.1
Accept: application/vnd.yourorg.users-v1+json
Here the client uses content negotiation for the specific resource she is interested in via the HTTP header
See https://www.mashery.com/blog/ultimate-solution-versioning-rest-apis-content-negotiation and http://blog.ploeh.dk/2015/06/22/rest-implies-content-negotiation/ for more details
Upvotes: 1
Reputation: 944
There are many ways, but most likely you want to keep the code as decoupled as possible. This makes keeping the versions in separate classes a good option:
V1Controller.java:
@RestController
@RequestMapping("/api/v1")
public class V1Controller{
// version 1 api
}
V2Controller.java :
@RestController
@RequestMapping("/api/v2")
public class V2Controller{
// version 2 api
}
But for a even higher degree of decoupling you could have two different webapps deployed on the same Tomcat or Jetty server - version 1 under the context path "/api/v1" and version 2 on the context path "/api/v2". The webapps would simply be builds of different versions of the same code (or builds of different branches - if you're using git).
Upvotes: 0
Reputation: 166
It really depends on your use case and what all is changing. There are technically many different paths you can take, but I will describe two that sound like they would work for you.
Create path param for v1 and add conditional that checks to see if the path param is v2 and call different method.
Create new path for api/v2, add changes functionality and call v1 endpoint method.
This really gets into specifics and should probably be evaluated on which way you should take it, depending on how the existing code is implemented.
Upvotes: 1