개발/Spring Boot

Spring Boot 고급 시리즈 5편 – REST API 버전 관리 전략: 실무에 강한 설계와 적용법

B컷개발자 2025. 4. 21. 23:30

Spring Boot에서 REST API 버전 관리 방법을 정리했습니다. URI, Header, Accept 방식의 실무 적용법과 마이그레이션 전략까지 단계별로 설명합니다.


Spring Boot 고급 시리즈 5편 – REST API 버전 관리 전략: 실무에 강한 설계와 적용법

API는 시간이 지날수록 진화하고, 이와 함께 기존 클라이언트를 보호하면서도 새로운 기능을 도입해야 하는 상황이 자주 발생합니다.
이때 필요한 것이 바로 **API 버전 관리(versioning)**입니다.

이번 글에서는 REST API의 버전 관리 전략을 비교하고,
Spring Boot에서 이를 어떻게 설계하고 구현하는지 실전 중심으로 정리해보겠습니다.


🧩 1. 왜 API 버전 관리가 필요한가?

  • 기존 클라이언트를 깨뜨리지 않고 새로운 기능 추가
  • 비즈니스 확장에 따른 필드 구조 변경 대응
  • 앱 클라이언트의 단계적 업그레이드 지원
  • 백오피스/제휴사 등 다양한 소비자 요구 대응

🔄 2. 대표적인 버전 관리 전략 비교

방식 예시 장점 단점

URI 방식 /api/v1/users 명확, 쉬운 디버깅 REST 원칙 위반 가능
Request Header X-API-VERSION: 1 URL 깔끔함 설정 복잡, 문서화 불편
Accept Header (MIME) Accept: application/vnd.company.v1+json REST 원칙 준수 복잡하고 직관성 낮음

✅ 3. Spring Boot에서의 실무 구현 방식


1️⃣ URI 방식 (가장 보편적)

@RestController
@RequestMapping("/api/v1/users")
public class UserV1Controller {
    @GetMapping
    public String getUsers() {
        return "v1 사용자 목록";
    }
}
@RestController
@RequestMapping("/api/v2/users")
public class UserV2Controller {
    @GetMapping
    public String getUsers() {
        return "v2 사용자 목록 (정렬 추가)";
    }
}
  • 경로만으로 직관적인 버전 관리 가능
  • Swagger 문서화도 용이
  • 실제 운영에서 가장 많이 사용되는 방식

2️⃣ Header 방식 – X-API-VERSION

@RestController
@RequestMapping("/api/users")
public class UserHeaderVersionController {

    @GetMapping
    public String getUsers(@RequestHeader("X-API-VERSION") String version) {
        if ("1".equals(version)) {
            return "v1 사용자 목록";
        } else if ("2".equals(version)) {
            return "v2 사용자 목록 (정렬 추가)";
        } else {
            throw new BusinessException(ErrorCode.INVALID_VERSION);
        }
    }
}
  • 클라이언트가 요청 Header에 버전 정보를 명시해야 함
  • URL은 고정되지만 내부 라우팅 로직 필요
  • API Gateway 또는 프록시 서버와 함께 사용하는 경우 많음

3️⃣ Accept Header (MIME 타입 기반)

Accept: application/vnd.myapp.v1+json
@GetMapping(produces = "application/vnd.myapp.v1+json")
public UserDto getUserV1() { ... }

@GetMapping(produces = "application/vnd.myapp.v2+json")
public UserDto getUserV2() { ... }
  • Spring에서 @GetMapping(produces = "...") 방식으로 MIME 타입 구분
  • RFC 표준에 가장 가까운 방식이지만 설정이 복잡하고 클라이언트 대응 어려움

🧠 실무 인사이트 – 어떤 방식이 가장 적절한가?

상황 추천 방식 이유

B2C 서비스 (앱 포함) URI 방식 유지보수 간편, 문서화 명확
API 게이트웨이 사용 Header 방식 내부 구현 분리 유리
고도화된 엔터프라이즈 환경 Accept Header 방식 RFC 기반 REST 추구 시 적합
외부 제휴사 대응 URI + Header 조합 유연한 대응 가능

🛠️ 마이그레이션 전략 예시

  1. /v1/과 /v2/ 공존
  2. 신규 기능은 /v2/에만 추가
  3. /v1/은 유지하되 6개월 후 종료 공지
  4. 클라이언트별 전환율 추적
  5. /v1/ 비활성화 (HTTP 410 Gone 처리 가능)

✅ 마무리 요약

항목 핵심 요약

버전 관리 필요성 API의 지속 가능성과 클라이언트 보호
URI 방식 가장 실용적, 운영 환경에서 선호
Header 방식 게이트웨이 및 내부 분리 전략에 유리
Accept 방식 REST 원칙에 가장 부합하나 복잡
마이그레이션 전략 공존 → 전환 유도 → 종료 순서 권장

📌 다음 편 예고

Spring Boot 고급 시리즈 6편: 비동기 처리와 이벤트 기반 아키텍처 – @Async와 도메인 이벤트 전략

 

LIST