ㅎㅇ


문제상황 


Spring Boot 4.0.1 + 스프링 프레임워크 7.0.2에서 새롭게 나온 API Versioning 사용해봤음.


근데 스웨거 ui


/swagger-ui.html 에 접근하면 400에러 뜨더라?

InvalidApiVersionException: 400 BAD_REQUEST "Invalid API version: 'No path segment at index 1'."

그래서 이걸 해결해본 과정을 설명하려함




처음에 400오류인 것도 안보고 아 맞다 시큐리티 설정 까먹고 있었노


이러면서 수정함


당연히 실패하지 ㅇㅇ 에러 메세지부터 api versioning문제인데.


그래도 설정은 했으니 조아쓰



그래서 


github.com/springdoc/springdoc-openapi/issues/3163


여기 이슈 보니까 `WebMvcConfigurer`의 `addPathPrefix`에서 springdoc을 제외하라고 하더라?




제외 했는데 실패함 ㅇㅇ


`addPathPrefix`는 URL prefix만 관리하는 거지, API version parsing 자체를 제어하지 않더라

에러 메시지가 조금 바뀌긴 했지만 여전히 400 에러.


GitHub 이슈를 다시 읽어보니, `addPathPrefix` 외에 커스텀 ApiVersionParser도 언급되어 있더라

Swagger UI 리소스(.html, .css, .js)에 대해서는 버전 파싱 자체를 건너뛰어야 한다고 하네?




여기서 configureApiVersioning으로 path segment versioning을 활성화하고 있었음 ㅇㅇ

문제는 모든 요청에 대해 버전 파싱을 시도하고 있음

/swagger-ui.html 같은 요청도 path segment index 1에서 버전을 찾으려고 하니 당연히 실패함



결국 


docs.spring.io/spring-framework/reference/web/webmvc-versioning.html

danvega.dev/blog/spring-boot-4-api-versioning


스프링 공식문서랑 기술블로그를 참고해봤음


스프링 공식문서에선 ApiVersionResolver라는 인터페이스가 있고, 요청에서 버전을 추출하는 역할을 한다고 되어있었고,

기술블로그에선 useVersionResolver()로 커스텀 resolver를 설정할 수 있다는 걸 알려 주더라


GitHub 이슈의 힌트와 조합해서, Swagger 경로에 대해서는 `null`을 반환하면 버전 파싱을 스킵할 수 있지 않을까 싶었음 ㅇㅇ




ui 경로 문제는 해결했음 ㅇㅇ


근데 InvalidApiVersionException: 400 BAD_REQUEST "Invalid API version: 'au.th'." 라는 오류가 뜨더라


내가 소셜로그인 api 테스트 해봤거든?


/au.th/login/google 같은 경로 있잖아 au.th를 버전으로 파싱하려다가 실패함


근데 이렇게 되면 제외해야할 경로만 끝도 없이 늘어나는 거잖슴?




그냥 나만의 방식으로 화이트리스트 방식으로 바꿈 ㅇㅇ


/api/v{N}/... 패턴에 매칭되는 경로에서만 버전을 추출하고 나머지는 모두 null 반환하도록 변경했음 ㅇㅇ


MissingApiVersionException: 400 BAD_REQUEST "API version is required."

근데 이딴 오류가 뜨네?


null을 반환해도 DefaultApiVersionStrategy가 버전이 필수라고 판단해서 예외를 던지고 있었음 ㅇㅇ



piotrminkowski.com/2025/12/01/spring-boot-built-in-api-versioning/



Spring Boot Built-in API Versioning - Piotr's TechBlogThis article explains how to use Spring Boot built-in API versioning feature to expose different versions of REST endpoints.piotrminkowski.com

다시 기술블로그 확인해봤는데 


기본적으로 버전이 필수라네?


null을 반환해도 버전 없음으로 처리되니 예외가 발생하는 거였음


ApiVersionConfigurer파일에 setVersionRequired(false)를 추가해서 버전이 없는 요청도 허용하도록 했음 ㅇㅇ


스웨거는 잘 뜨더라


근데 API 목록이 비어있었음 ㅇㅇ


No operations defined in spec!


이런 오류 뜨더라


Swagger가 버전별 API를 제대로 인식하지 못하고 있는 거였음




springdoc이 @RequestMapping(version = "1.0") 어노테이션을 인식해서 버전별로 API를 그룹화하도록 설정해야 했음 ㅇㅇ


결과는 성공했음 ㅇㅇ


그리고 처음엔


addSupportedVersions("1", "2") 형태로 사용했는데

Spring Framework 공식 예제를 보니 시맨틱 버저닝(`"1.0"`, `"2.0"`)을 사용하고 있더라고







그래서 나도 싹다 바꿈 ㅇㅇ 


나만의 방법이란건 별거없음 그냥 화이트 리스트로 한게 나만의 코법임 ㅋㅋ


사실 이렇게 까지 하면서 느낀건

/api/v1/users 가 더 편한 것 같음 ㅋㅋㅋ


뻘짓인 것 같으면 CEX