| name | api-versioning |
| description | Version REST endpoints with Spring Framework 7's first-class API versioning — the `version` attribute on @GetMapping/@RequestMapping plus ApiVersionConfigurer, instead of manual path routing or separate controllers. Use when a task in a Boot 4 / FW 7 project is about evolving an API you EXPOSE while keeping old clients working — "v1 vs v2 endpoint", "version this response", header/media-type/path versioning, deprecation/Sunset headers — even if the user never mentions a version (check the build file). Do NOT use for choosing a client to CALL a versioned API (see http-interface-clients), or for general request mapping unrelated to versions. |
API versioning (Spring Framework 7)
Baseline: Spring Boot 4.0+, Spring Framework 7.0+, Java 17+ (25 recommended).
Framework 7 adds a version attribute to request-mapping annotations plus an ApiVersionConfigurer
to pick the versioning strategy. Claude gets this wrong by hand-rolling version routing — separate
/api/v1/... and /api/v2/... paths, manual Accept-header parsing, or duplicate controllers. In
FW 7 the framework resolves the version and routes for you.
When to use / not use
Use to serve multiple versions of an endpoint you own. Do NOT use this to consume a versioned
API — that's http-interface-clients (set the version header on the client). For plain, unversioned
routing, ordinary @GetMapping is fine.
The idiom
1. Enable a versioning strategy via WebMvcConfigurer:
@Configuration
public class ApiVersioningConfig implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer
.useMediaTypeParameter(MediaType.APPLICATION_JSON, "version")
.setDefaultVersion("1.0");
}
}
2. Tag handlers with version — same path, the framework dispatches by version:
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping(version = "1.0")
public UserDTOv1 getUserV1(@PathVariable Long id) { ... }
@GetMapping(version = "2.0")
public UserDTOv2 getUserV2(@PathVariable Long id) { ... }
}
3. Clients select the version (media-type-parameter strategy shown):
curl -H "Accept: application/json;version=1.0" http://localhost:8080/api/users/1
curl -H "Accept: application/json;version=2.0" http://localhost:8080/api/users/1
Gotchas
- Pick one strategy in
configureApiVersioning and use it consistently; the version attribute
is interpreted according to it.
version = "1.1+" matches "1.1 or higher" — handy for "current and forward" handlers so you don't
re-tag every minor bump.
- Set
setDefaultVersion(...) so requests with no version still resolve rather than erroring —
versions are required by default (setVersionRequired(true) is the default).
- Pair with RFC-compliant
Deprecation, Sunset, and Link response headers to signal v1 retirement
— versioning is the routing half; the headers are how clients learn to migrate.
References