OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 37 / 90
stack-analysis
CHAPTER 37 / 90
읽기 약 2
FUNCTION

API 버저닝 전략


핵심 개념

URL·Header·Accept-Version 비교·Deprecation·Sunset — 호환성 유지.

본문

3가지 버저닝 방식

📋 코드 (12줄)
1. URL Path: /v1/users, /v2/users
   ✅ 명확·캐싱·테스트 쉬움
   ❌ URL 변경 = 새 리소스처럼 보임
   → 가장 인기

2. Custom Header: X-API-Version: 2
   ✅ URL 깔끔
   ❌ 헤더 누락 시 혼란

3. Accept Header: Accept: application/vnd.api.v2+json
   ✅ HTTP 표준
   ❌ 디버깅 어려움

URL 버저닝 (권장)

TYPESCRIPT📋 코드 (35줄)
// app.ts
import v1Routes from './routes/v1';
import v2Routes from './routes/v2';

app.use('/api/v1', v1Routes);
app.use('/api/v2', v2Routes);


// routes/v1/user.routes.ts (레거시 유지)
router.get('/users/:id', (req, res) => {
  const user = await userService.findById(req.params.id);
  res.json({
    id: user.id,
    name: user.name,
    email: user.email,
  });
});


// routes/v2/user.routes.ts (개선)
router.get('/users/:id', (req, res) => {
  const user = await userService.findById(req.params.id);
  res.json({
    id: user.id,
    profile: {        // 그룹화
      displayName: user.name,
      email: user.email,
      avatar: user.avatarUrl,
    },
    metadata: {
      createdAt: user.createdAt,
      lastSeenAt: user.lastSeenAt,
    },
  });
});

Deprecation 헤더

TYPESCRIPT📋 코드 (21줄)
// v1 라우트에 자동 경고
function deprecate(sunset: string, alternative: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    res.setHeader('Deprecation', 'true');
    res.setHeader('Sunset', new Date(sunset).toUTCString());
    res.setHeader('Link', `<${alternative}>; rel="successor-version"`);
    next();
  };
}


app.use('/api/v1', deprecate(
  '2026-12-31',
  'https://api.example.com/v2'
));


// 응답 헤더:
// Deprecation: true
// Sunset: Wed, 31 Dec 2026 00:00:00 GMT
// Link: <https://api.example.com/v2>; rel="successor-version"

점진적 마이그레이션

TYPESCRIPT📋 코드 (26줄)
// v1과 v2 데이터 모델 변환 레이어
class UserSerializer {
  static v1(user: User) {
    return { id: user.id, name: user.name, email: user.email };
  }

  static v2(user: User) {
    return {
      id: user.id,
      profile: { displayName: user.name, email: user.email },
      metadata: { createdAt: user.createdAt },
    };
  }
}


// 같은 DB 모델, 다른 직렬화
router.get('/v1/users/:id', async (req, res) => {
  const user = await userService.findById(req.params.id);
  res.json(UserSerializer.v1(user));
});

router.get('/v2/users/:id', async (req, res) => {
  const user = await userService.findById(req.params.id);
  res.json(UserSerializer.v2(user));
});

호환성 유지 원칙

📋 코드 (15줄)
✅ 절대 안전 (Backward Compatible):
- 새 필드 추가
- 새 엔드포인트
- 새 enum 값 (클라이언트가 unknown 처리 시)
- HTTP 200 → 추가 필드

❌ Breaking Change:
- 필드 제거
- 필드 타입 변경 (string → number)
- enum 값 제거
- HTTP 응답 코드 변경
- URL 변경


→ Breaking은 새 버전, 그 외는 같은 버전 유지

클라이언트 라이브러리

TYPESCRIPT📋 코드 (22줄)
// SDK 자동 마이그레이션 도움
import { ApiClient } from '@my/sdk';

const client = new ApiClient({
  apiKey: '...',
  version: 'v2',  // 또는 'latest'
});


// SDK 내부 — 자동 변환
class ApiClient {
  async getUser(id: string) {
    const res = await fetch(`/${this.version}/users/${id}`);
    const data = await res.json();

    // v1 응답을 v2 형태로 자동 변환 (같은 인터페이스)
    if (this.version === 'v1') {
      return { profile: { displayName: data.name, email: data.email }, ... };
    }
    return data;
  }
}

마이그레이션 시간표

📋 코드 (18줄)
[Phase 1: 출시] 2026-04
- v2 출시 + 문서화
- v1, v2 동시 운영

[Phase 2: 안내] 2026-07
- v1 응답에 Deprecation 헤더
- 사용자에게 이메일

[Phase 3: 강제 안내] 2026-10
- v1 호출 시 응답 본문에 경고
- 대시보드에 마이그레이션 진행률

[Phase 4: 종료] 2026-12-31 (Sunset)
- v1 410 Gone 응답
- 또는 v2로 자동 리다이렉트


→ 최소 6~12개월 마이그레이션 기간

다음 챕터

CH.38 "GraphQL vs REST: 실전 선택 기준".


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 코드의 API 버저닝 부분을 분석해서
실전 분석 + 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

API 버저닝 관련 인기 라이브러리/패턴 5개를
비교 분석해서 패턴 추출를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 API 버저닝
최적화 가능 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 백엔드 시장의
API 버저닝 트렌드를 솔직히 알려줘.

⭐ 이것만 기억하세요
API 버저닝 전략 이 3가지만 확실히 잡으세요
1.URL 버저닝(/v1, /v2)이 가장 명확 — 캐싱·디버깅 쉬움
2.Backward Compatible 변경(필드 추가)은 같은 버전 유지
3.Deprecation + Sunset 헤더 + 6~12개월 마이그레이션 기간


공유하기
진행도 37 / 90