Versioning your API with Spring Framework
Let’s see how to implement 4 different versioning strategies using Spring Framework:
If you would like to learn more about these strategies, I’ve written about it here: Versioning Your REST API Made Easy: Tips and Tricks
URL path strategy
We can define the versioning in the path URL, having something like this:
@RestController
public class PathController {
@GetMapping("/v1/path")
public ResponseEntity getValuesV1() {
return ResponseEntity.ok("Path v1");
}
@GetMapping("/v2/path")
public ResponseEntity getValuesV2() {
return ResponseEntity.ok("Path v2");
}
}
To call this API is easier, we only have to pass the versioning in the path. For example:
GET http://localhost:8080/v1/path
Query parameter
This strategy uses the path parameter to define the versioning. We can do that in spring by adding the version parameter to the method.
@RestController
@RequestMapping("/query")
public class QueryParamController {
@GetMapping(params = "v=1")
public ResponseEntity getValuesV1() {
return ResponseEntity.ok("Query v1");
}
@GetMapping(params = "v=2")
public ResponseEntity getValuesV2() {
return ResponseEntity.ok("Query v2");
}
}
Unlike the previous one, in this case we need to pass the versioning through the path variables. For example:
GET http://localhost:8080/query?v=1
HTTP header
We can define a custom header to use for versioning our REST API. This can be achieved with the following code.
@RestController
@RequestMapping("/header")
public class HeaderController {
@GetMapping(headers = "X-Version=1")
public ResponseEntity getValuesV1() {
return ResponseEntity.ok("Header v1");
}
@GetMapping(headers = "X-Version=2")
public ResponseEntity getValuesV2() {
return ResponseEntity.ok("Header v2");
}
}
To call this API we have to pass a custom header in the request. For example:
GET http://localhost:8080/header
X-Version: 1
Content negotiation
This strategy is more aligned with the best practices of REST. It consists of passing the versioning through the content-type header.
@RestController
@RequestMapping("/content-negotiation")
public class ContentNegotiationController {
@GetMapping(produces = "application/vnd.my.api.v1+json")
public ResponseEntity getValuesV1() {
return ResponseEntity.ok("Content Negotiation v1");
}
@GetMapping(produces = "application/vnd.my.api.v2+json")
public ResponseEntity getValuesV2() {
return ResponseEntity.ok("Content Negotiation v2");
}
}
We can call this API by passing the versioning in the content-type. For example:
GET http://localhost:8080/content-negotiation
Content-Type: application/vnd.my.api.v1+json
Conclusion
Spring Framework gives many ways to apply versioning to our REST API. The most important thing is to define which one you want to use in your application and guarantee you follow a standard through all your APIs.
If this content has been useful for you, please, leave a like ❤️