Ticker

6/recent/ticker-posts

API Versioning on Spring Boot 4 with Java 25


Spring Framework shape Java Enterprise development for decades. It's started in 2004.

  • 2004 - Version 1.0 - First production-ready release.
  • 2006 - Version 2.0 - Simplified XML configuration and introduced custom namespaces.
  • 2009 - Version 3.0 - Java 5 support, Spring Expression Language (SpEL), and Java-based configuration.
  • 2013 - Version 4.0 - First version with full support for Java 8.
  • 2017 - Version 5.0 - Introduction of Spring WebFlux (reactive programming)
  • 2022 - Version 6.0 - Baseline moved to Java 17+ and Jakarta EE9.
  • 2025 - Version 7.0 - Latest major generation focusing on Java 25 and modern cloud ecosystem.
Later something excited came out. It called Spring Boot to support auto configurations and production ready.

By now Spring Boot reached version 4 and supported Java 25. Spring Boot 4 released with many features. Learn more here.

There are 2 features is my favorite:
  1. API Versioning
  2. HTTP Service Client Enhancements
In this blog I'll cover only API Versioning. In the past each backend team they have different approach for API Versioning. 

For a simple example, flight booking system have two main backend components.
  • Booking: support by booking team to record booking information from user.
  • Checkout: support by payment team to handle payment transactions.
Front end (Web UI) team has to integrate into both components. If both backends didn't have consistent approach. UI will cost double effort to integrate. 

Imagine the backend have different API for mobile and other external system integration. Managing the version might became messy.

Spring Boot saw this problem; they came up with 4 standards strategy. In your project, you can use only one strategy across project.
  1. Path Segment Versioning
  2. Request Header Versioning
  3. Query Parameter Versioning
  4. Media Type Versioning
Additional configuration is needed to make API version work. As always spring boot offer Java class configuration or properties configuration.

Without version strategy configuration, your application will throw below error.

Caused by: java.lang.IllegalStateException: API version specified, but no ApiVersionStrategy configured
	at org.springframework.util.Assert.state(Assert.java:80) ~[spring-core-7.0.1.jar:7.0.1]
	at org.springframework.web.servlet.mvc.method.RequestMappingInfo$DefaultBuilder.build(RequestMappingInfo.java:773) ~[spring-webmvc-7.0.1.jar:7.0.1]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.createRequestMappingInfo(RequestMappingHandlerMapping.java:385) ~[spring-webmvc-7.0.1.jar:7.0.1]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.createRequestMappingInfo(RequestMappingHandlerMapping.java:289) ~[spring-webmvc-7.0.1.jar:7.0.1]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getMappingForMethod(RequestMappingHandlerMapping.java:207) ~[spring-webmvc-7.0.1.jar:7.0.1]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getMappingForMethod(RequestMappingHandlerMapping.java:80) ~[spring-webmvc-7.0.1.jar:7.0.1]
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$0(AbstractHandlerMethodMapping.java:279) ~[spring-webmvc-7.0.1.jar:7.0.1]
	... 28 common frames omitted

1. Path Segment Versioning

Java class configuration

package com.bannalycode.springbootapiversion;  
  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer;  
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  
  
@Configuration  
public class APIVersionConfig implements WebMvcConfigurer {  
  
  @Override  
  public void configureApiVersioning(ApiVersionConfigurer configurer) {  
        configurer.usePathSegment(1).addSupportedVersions("1.0", "2.0").setDefaultVersion("1.0");  
    }  
}

Properties configuration

spring.mvc.apiversion.default=1.0  
spring.mvc.apiversion.supported=1.0,2.0  
spring.mvc.apiversion.use.path-segment=1

REST Controller Class

@RestController  
@RequestMapping("/api")  
public class APIVersionRestController {  
  
    @GetMapping( value = "/{version}/version", version = "1.0")  
    public String getVersionOne() {  
        return "version one";  
    }  
  
    @GetMapping(value = "/{version}/version", version = "2.0")  
    public String getVersionTwo() {  
        return "version two";  
    }  
}

2. Header Versioning

Java class configuration

@Configuration  
public class APIVersionConfig implements WebMvcConfigurer {  
  
  @Override  
  public void configureApiVersioning(ApiVersionConfigurer configurer) {  
        configurer.useRequestHeader("Server-API-Version").addSupportedVersions("1.0", "2.0").setDefaultVersion("1.0");  
    }  
}

Properties configuration

spring.mvc.apiversion.default=1.0  
spring.mvc.apiversion.supported=1.0,2.0  
spring.mvc.apiversion.use.header=Server-API-Version

REST Controller Class

@RestController  
@RequestMapping("/api")  
public class APIVersionRestController {  
  
    @GetMapping( value = "/version", version = "1.0")  
    public String getVersionOne() {  
        return "version one";  
    }  
  
    @GetMapping(value = "/version", version = "2.0")  
    public String getVersionTwo() {  
        return "version two";  
    }  
}

3. Query Parameter Versioning

Java Configuration

@Configuration  
public class APIVersionConfig implements WebMvcConfigurer {  
  
  @Override  
  public void configureApiVersioning(ApiVersionConfigurer configurer) {  
        configurer.useQueryParam("version").addSupportedVersions("1.0", "2.0").setDefaultVersion("1.0");  
    }  
}

Properties Configuration

spring.mvc.apiversion.default=1.0  
spring.mvc.apiversion.supported=1.0,2.0  
spring.mvc.apiversion.use.query-parameter=version

4. Media Type Versioning

Java Configuration

@Configuration  
public class APIVersionConfig implements WebMvcConfigurer {  
  
  @Override  
  public void configureApiVersioning(ApiVersionConfigurer configurer) {  
        configurer.useMediaTypeParameter(MediaType.APPLICATION_JSON, "version").addSupportedVersions("1.0", "2.0").setDefaultVersion("1.0");  
    }  
}

Properties Configuration

spring.mvc.apiversion.default=1.0  
spring.mvc.apiversion.supported=1.0,2.0  
spring.mvc.apiversion.use.media-type-parameter[application/json]=version


Post a Comment

0 Comments