Versioning your API with Spring Framework

Thiago Bomfim
2 min readJan 4, 2025

--

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 ❤️

--

--

Thiago Bomfim
Thiago Bomfim

Written by Thiago Bomfim

I'm a happy developer, trying to help the world and peoples with technologic

No responses yet