본문 바로가기
dev/spring

Spring Framework 7.0.0 API Versioning

by igooo 2025. 7. 31.
728x90

개요

이번 포스팅에는 Spring Framework 7.0.0에 포함될 API Versioning 기능에 대해서 알아보자.

Restful API로 클라이언트와 통신하는 서비스에서는 URI에 버전을 포함하여(ex /service/v1.0/users) API를 작성하고, API가 변경됨에 따라 API의 버전을 추가하거나 변경하는 전략을 사용해 왔다. Spring Framework 7.0.0에는 기존에 URI를 설정하던 @RequestMapping 어노테이션에 version 어트리뷰트를 추가하여 API Version을 관리하는 기능을 제공한다.

 

API Versioning을 사용하는 이유

  • 하위 호환성 유지 (Backward Compatibility)
  • 점진적 마이그레이션 (Gradual Migration)
  • API 진화 관리 (API Evolution Management)
  • 클라이언트별 요구사항 대응

 

Getting Started

사용자 정보를 응답하는 API를 작성하고 버전별로 응답할 수 있도록 프로젝트를 구성해 본다.

 

프로젝트 생성

Spring Framework 7.0.0 버전을 사용하도록 Spring initializr를 사용하여 프로젝트를 생성한다.

게시글 작성일 기준 Spring Boot 4.0.0-SHAPSHOT을 사용하면 Spring Framework 7.0.0-M7 버전으로 사용 가능하다.

plugins {
    id 'java'
    id 'org.springframework.boot' version '4.0.0-SNAPSHOT'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'org.igooo'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

repositories {
    mavenCentral()
    maven { url = 'https://repo.spring.io/snapshot' }
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
    useJUnitPlatform()
}

 

API Versioning

사용자를 조회하는 API(/user/{id})를 4가지 버전 1.0, 1.1, 1.2, 1.5 버전으로 제공하도록 Controller를 추가한다.

@RestController
@RequestMapping("/user/{id}")
class ApiVersionController {
    @GetMapping(version = "1.0")
    User findUser1_0() {
        return new User(0, "igooo", null);
    }

    @GetMapping(version = "1.1")
    User findUser1_1() {
        return new User(1, "igooo", "1.1");
    }

    @GetMapping(version = "1.2+")
    User findUser1_2() {
        return new User(2, "igooo", "1.2");
    }

    @GetMapping(version = "1.5")
    User findUser1_5() {
        return new User(3, "igooo", "1.5");
    }
}

 

Spring Framework에서 API Version 관리를 활성화하기 위해서는 ApiVersionConfigurer를 사용하여 설정을 추가해야 한다.

ApiVersionConfigurer를 사용하여 설정된 항목은 ApiVersionStrategy 클래스를 사용하여 Spring에서 API Version을 처리하는 데 사용된다.

@Configuration
class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureApiVersioning(ApiVersionConfigurer configurer) {
        configurer.useRequestHeader("X-API-Version");

        configurer.detectSupportedVersions(true);
        configurer.addSupportedVersions("1.3");

        configurer.setDefaultVersion("1.0");
    }
}

 

위 코드에서 설정된 내용은 아래와 같다.

  • API 버전은 X-API-Version Header를 사용하여 설정한다.
  • Controller에서 명시하지 않은 버전을 지원한다. (ex 1.3)
  • 버전을 명시하지 않은 경우 1.0 버전을 기본 버전으로 사용한다.

상세한 설정 내용은 문서를 참고한다. https://docs.spring.io/spring-framework/docs/7.0.0-M6/javadoc-api/org/springframework/web/servlet/config/annotation/ApiVersionConfigurer.html

 

위 코드에서 별도로 설정을 추가하지는 않았지만 버전 정보는 SemanticApiVersionParser를 사용하여 파싱 된다. SemanticApiVersionParser를 사용하면 일반적으로 많이 사용되는 "1", "1.0", "1.2", "1.2.0", "1.2.3" 형태의 버전을 파싱 할 수 있다. 별도의 버전값을 사용한다면 ApiVersionParser 인터페이스를 구현하여 사용할 수도 있다.

 

API Version 기능 테스트 

Version을 지정하지 않고 호출

Version을 지정하지 않고 호출하면 default로 설정된 버전으로 API가 응답한다.

{"id":0,"name":"igooo","version":null}

 

Version: 1.1

Version 1.1의 API가 응답한다.

{"id":1,"name":"igooo","version":"1.1"}

 

Version: 1.2

Version 1.2의 API가 응답한다.

{"id":2,"name":"igooo","version":"1.2"}

 

Version: 1.3

Controller에는 버전 1.3에 해당하는 API가 없지만 Support Version으로 추가한 1.3 버전은 1.2 버전보다는 상위 버전이고, 1.5 버전보다는 하위 버전으로 임으로 1.2 버전의 API가 응답한다.

{"id":2,"name":"igooo","version":"1.2"}

 

Version: 1.4

API Version 관리가 활성화된 경우 버전이 필수이며 버전이 없거나(MissingApiVersionException) 요청된 버전이 지원되지 않는 버전이면(InvalidApiVersionException) 오류가 발생되고 클라이언트로 HTTP 400으로 응답한다.

HTTP ERROR 400

 


Version: 1.5

Version 1.5의 API가 응답한다.

{"id":3,"name":"igooo","version":"1.5"}

 

 

마무리

Spring Framework 7.0.0에 추가될 API Versioning에 대하여 알아보았다. 기존에 Path로만 관리하던 API 버전을 Spring의 기능을 사용하여 쉽게 관리할 수 있게 되었다. 정식버전으로 릴리즈 되면 서비스에 적용해 보도록 하자.

 

예제에 사용된 전체 소스 코드는 GitHub에서 확인할 수 있다.

 

참고

 

728x90