최근 API 버전관리하는 이슈를 진행하였는데 원하는 방향으로 버저닝을 하려니 원하는 정보를 찾는데 시간이 꽤 걸려서 정리해두면 나중에 누군가에게 도움이 될 것 같아 오랜만에 포스팅을 작성해봅니다.
1. API Versioning method
API의 버전 관리 하는 방법으로 아래 4가지를 이용한 버저닝을 주로 하고 있습니다.
- URI Path
- Query Parameters
- Request Header
- Contetnt Negotiation(MIME Type)
2. How to?
a. URI Path
말그대로 URI 경로에 API버전 정보를 담아서 버전관리를 합니다.
가장 일반적인 방법이기도 하고
# version 1
GET http://{host}/v1/example
# version 2
GET http://{host}/v2/example
위 처럼 적용되는 케이스를 말하는데, 가장 쉽고 단순하게 버전을 구분할 수 있다는 장점이 있습니다.
다만 이 방법으로 진행할 때엔, 소스코드 관리 측면에서 고려할 부분이 생깁니다.
간단한 예로, API 메서드 자체를 새롭게 추가하거나 컨트롤러 자체를 분기하는 등 작업이 필요하기 때문에 소스관리 측면에서 고려해봐야합니다.
b. Query Parameter
Request Parameter에 버전 값을 추가하여 관리합니다.
# version 1
GET http://{host}/example?version=1
# version 2
GET http://{host}/example?version=2
위 처럼 버전값을 받아서 사용하는 방법이며, 몇가지 장점이 있습니다.
장점 1. 구현이 간단하다.
장점 2. 버전 업데이트 시 클라이언트에서 업데이트된 버전정보를 쉽게 요청할 수 있고, 파라미터 누락시 Default value를 소스에 정의해두어 최신버전을 사용하도록 유도할수도 있습니다.
c. Request Header - Custom
Request Header에 자체적으로 설정한 값으로 버전 관리합니다.
# Request 예시
GET /example HTTP/1.1
Host: {host}
Content-Type: application/json
X-API-Version: 1
Version 1 을 요청한다고 가정했을 때 요청 파라미터를 위처럼 정의하는 방식입니다.
헤더 중에 "X-API-VERSION"처럼 커스텀한 키네이밍을 추가하는 방법으로 주로 많이 사용합니다.
이때 X- 가 의미하는 바는
위에 소개해드린 두가지방법(URI Path, Query Param)보다 구현하며 신경써야할 점이 있지만,
URI Path를 간결하게 유지할 수 있고, 일반 브라우저에서의 무분별한 접근을 통제할 수 있다는 장점을 갖고있습니다.
d. Content Negotiation(MIME Type)
Request Header 중 Accept, Content-Type 키를 이용하여 버저닝을 하는 방법입니다.
주로 REST API를 구현할 때 사용되는 방법입니다.
# Request 예시
GET /example HTTP/1.1
Host: {host}
Accept: application/vnd.example.v1+json
Content-Type: application/vnd.example.v1+json
Accept 헤더는 클라이언트가 어떤 데이터 타입으로 응답 받을것인지,
Content-Type 헤더는 클라이언트에서 보내는 요청의 데이터 타입을 정의하는데요.
위 헤더들에 버전값을 커스텀하게 넣어주어 버저닝하는 방법입니다.
서치하던중에 헤더 값에 vnd.example.. 은 무엇을 의미하는지, 아무렇게나 써도되는지가 궁금해서 시간을 좀 들이게 되었는데,
vnd는 vendor를 뜻하며, 해당 API의 공급업체를 뜻하는것으로 이해했습니다.
위 응답코드 예시 중 vnd.example 에는 보통 vnd.company name이 들어간다고 합니다.
Media Type(MIME Type)의 경우 공식적으로 사용되는 값은 iana에 정의 되어있는데요(https://www.iana.org/assignments/media-types/media-types.xhtml)
공개적인 상용 API를 구성할때는 register해두어 사용하는것이 일반적이고, 비공개적으로 사용할 API인 경우 옵셔널한 사항이라고 하네요.
만약 jseastar 라는 회사의 프러덕트를 개발하며 내부적으로 사용되는 API에 대한 버저닝을 하고자한다면,
Accept/Content-Type 헤더에 "application/vnd.jseastar.v1+json" 처럼 값을 넣어줄 수 있겠네요.
위 방법으로 API Versioning을 할 때 얻을 수 있는 장점으로는,
1. 코드베이스에서 각 API들을 독립적으로 구성하기에 유용함
2. 불필요한 API 추가작성이 필요없어지는 점
3. 더욱 유연한 버전관리
정도가 될 것 같네요.
다만 구현/테스트가 URI, Query Param 방식보다는 복잡하다는 점과,
클라이언트에서 요청할 때 버전정보를 명확하게 알아야한 요청이 가능하다는 점이 있겠네요.