Spring Framework 7.0 - API Version
A good API evolves. A great API evolves without breaking trust.
Spring Framework 7.0, released on November 13, 2025, introduces several new features, and one of the most useful for API work is the new API versioning support.
Spring now provides a clean, built-in way to configure API versions using the ApiVersionConfigurer. You can set up versioning through Java configuration or application.properties, define default versions, and even configure deprecation handling.
In this guide, we look at a simple example using a custom HTTP header (x-version) as the versioning strategy.
Configuring API Versioning
The first step is to implement the configureApiVersioning method:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
StandardApiVersionDeprecationHandler deprecationHandler =
new StandardApiVersionDeprecationHandler();
LocalDateTime deprecatedDate = LocalDateTime.of(2026, 5, 30, 0, 0);
deprecationHandler.configureVersion(”v1”)
.setDeprecationDate(ZonedDateTime.of(deprecatedDate, ZoneId.of(”UTC”)));
configurer
.useRequestHeader(”x-version”)
.addSupportedVersions(”v1”, “v2”)
.setDeprecationHandler(deprecationHandler)
.setDefaultVersion(”v2”);
}
}
In this configuration:
We support two API versions: v1 and v2
v1 is marked as deprecated
Spring automatically adds a Deprecation header following RFC 9745
You can also implement a Sunset header (RFC 8594) if needed
The default version is v2
Versioning in the Controller
Now let’s see a simple controller using versioned mappings.
@RestController
public class ApplicationController {
private final ApplicationService applicationService;
public ApplicationController(ApplicationService applicationService) {
this.applicationService = applicationService;
}
@GetMapping(value = “/app”, version = “v1”)
public ResponseEntity<List<Application>> getApp() {
return ResponseEntity.ok(applicationService.findAll().join());
}
@GetMapping(value = “/app”, version = “v2”)
public ResponseEntity<List<Application>> getAppV2() {
return ResponseEntity.ok(applicationService.findAll().join());
}
}
What the Response Looks Like
Calling v1
HTTP/1.1 200
Deprecation: @1780099200
Content-Type: application/json
You receive a Deprecation header because v1 has an expiry date.
Calling v2
HTTP/1.1 200
Content-Type: application/json
Conclusion
In my opinion, this approach may not be the most practical solution for HTTP API versioning itself, but it is extremely helpful for:
applying RFC 9745 (Deprecation header)
applying RFC 8594 (Sunset header)
validating API versions and returning clear exceptions
keeping your API evolution predictable and well-structured
If you want to dive deeper, here are two great resources:
📘 https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/api-version.html
📘 https://www.danvega.dev/blog/spring-boot-4-api-versioning?ref=apisyouwonthate.com
You can access the code here: https://github.com/ThiagoBfim/spring-news


