Mastering API Versioning in Spring Framework 7.0: Strategies and Code Samples
This article explains why API versioning is essential for modern web development, outlines common versioning strategies such as URI, header, query‑parameter and content‑negotiation approaches, and demonstrates how Spring Framework 7.0 natively supports version‑specific routing on both server and client sides with practical code examples.
API Versioning Importance
API version control allows developers to introduce new features, fix bugs, or change data structures while maintaining backward compatibility.
URI versioning : include version in URL path, e.g. /api/v1/users.
Header versioning : specify version via request header, e.g. Accept: application/vnd.company.app-v1+json.
Query parameter versioning : pass version as query parameter, e.g. /api/users?version=1.
Content negotiation versioning : determine version from media type in Accept header.
Spring 7.0 API Versioning
Spring Framework 7.0 adds native support for API versioning. By specifying a version range in @RequestMapping, requests are routed to different controller methods, simplifying multi‑version API management.
Implementation
Developers declare version ranges in @RequestMapping. Versions can be resolved from:
Request URL path : e.g. /api/v1/users or /api/v2/users.
Request header value : e.g. Accept: application/vnd.company.app-v1+json.
Custom sources : developers can configure additional resolvers.
Example controller with two API versions:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@RequestMapping(value = "/api/users", version = "1.0")
public ResponseEntity<List<UserV1>> getUsersV1() {
// version 1.0 implementation
List<UserV1> users = fetchUsersV1();
return ResponseEntity.ok(users);
}
@RequestMapping(value = "/api/users", version = "2.0")
public ResponseEntity<List<UserV2>> getUsersV2() {
// version 2.0 implementation
List<UserV2> users = fetchUsersV2();
return ResponseEntity.ok(users);
}
}The endpoint /api/users dispatches to the appropriate method based on the requested version (1.0 or 2.0). Versions can be supplied via URL path or request header.
Client API Versioning
Spring 7.0 also enhances client support. Using WebClient, developers can set the desired API version in the request header.
Client Example
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class UserClient {
private final WebClient webClient;
public UserClient(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("http://example.com").build();
}
public Mono<List> getUsersV1() {
return webClient.get()
.uri("/api/users")
.accept(MediaType.valueOf("application/vnd.company.app-v1+json"))
.retrieve()
.bodyToMono(List.class);
}
}By setting the Accept header to application/vnd.company.app-v1+json, the client ensures it talks to version 1.0 of the API.
Source Code Analysis
Key classes include ApiVersionResolver, PathApiVersionResolver, DefaultApiVersionStrategy, and VersionRequestCondition. These work together to parse, validate, and route requests based on version information, and can be extended for custom strategies.
Conclusion
Spring Framework 7.0 provides a flexible, extensible API versioning mechanism that supports common strategies and allows custom implementations, enabling developers to manage multiple API versions in a standardized way.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
