🤔 Question
👉 이런 URI 본 적 있으신가요?
/api/v1/users
/api/v2/users
/api/v3/users
처음에는 안전해 보입니다.
"버전 올리면 이전 API는 그대로 두면 되잖아요?"
하지만 시간이 지나면
👉 v1, v2, v3… 끝없이 쌓인 API가 시스템을 무겁게 만듭니다.
버저닝은 문제를 해결하는 것 같지만
사실은 계약 관리 실패를 뒤로 미루는 방법일 뿐입니다.
🎯 v1, v2가 계속 늘어나는 이유
버전을 올리는 가장 흔한 이유는 이것입니다.
"필드를 하나 바꿔야 하는데
기존 소비자가 깨질까 봐 새 버전 만들었어요."
즉,
👉 하위 호환성을 지키는 방법을 모르기 때문입니다.
버전은 안전장치가 아니라
계약 설계를 포기했다는 신호가 됩니다.
🎯 깨지는 변경 vs 안전한 변경
// 깨지는 변경
{
"id": 10,
"name": "Alice"
}
// name → username 로 변경
{
"id": 10,
"username": "Alice"
}
이 변경은 기존 소비자를 즉시 깨뜨립니다.
그래서 보통 v2를 만듭니다.
하지만 이렇게 바꾸면 어떨까요?
// 안전한 진화
{
"id": 10,
"name": "Alice",
"username": "Alice"
}
기존 소비자는 name을 계속 쓰고
새 소비자는 username을 사용합니다.
👉 이것이 하위 호환성을 지키는 API 진화입니다.
🎯 버저닝 없는 API의 핵심 규칙
버전을 올리지 않고 API를 진화시키려면
명확한 규칙이 필요합니다.
✔ 기존 필드는 삭제하지 않는다
✔ 기존 필드의 의미를 바꾸지 않는다
✔ 새 필드는 항상 선택적으로 추가한다
✔ 기본값으로 기존 동작을 유지한다
👉 계약을 확장만 하고 수정하지 않는 것이 핵심입니다.
🎯 Consumer-Driven Contract Test
하위 호환성을 말로만 지키는 것은 위험합니다.
👉 소비자가 기대하는 계약을 테스트로 고정해야 합니다.
Consumer-Driven Contract Test는
"소비자가 기대하는 응답 형태"를 테스트로 저장합니다.
API 제공자가 변경을 배포할 때
이 테스트가 실패하면
깨지는 변경이 배포 단계에서 차단됩니다.
🎯 진짜 버저닝은 URI가 아니라 계약이다
URI에 v1, v2를 붙이는 것은
겉으로 드러난 버전일 뿐입니다.
진짜 버전은
👉 계약 스키마의 변경 이력입니다.
스키마가 안전하게 진화하면
URI 버전은 필요 없어집니다.
☔ 정리
👉 v1, v2는 문제 해결이 아니라 문제 연기의 결과입니다.
👉 하위 호환성 규칙이 곧 API 진화 전략입니다.
👉 진짜 버저닝은 URI가 아니라 계약 스키마에 있습니다.
계약을 깨지 않고 확장할 수 있다면,
API는 평생 v1로도 충분합니다.
If I was of any help to you, please buy me coffee 😿😢😥
If you have any questions, please leave them in the comments
[2] Ads : https://apps.apple.com/us/app/beluga-classic-film-filters/id6744041061