REST API를 개발하면서 버전이 올라가도 기존 버전의 API는 사용할 수 있도록 하고싶어 이 포스팅을 작성한다.
클라이언트는 API 버전이 변경될 때마다 애플리케이션을 업데이트하고 싶지 않을 수 있다. API버전을 관리한다면 새로운 버전을 만들되, 이전 버전을 계속 유지할 수 있을 것이다.
이전에 진행했던 프로젝트에서는 버전을 관리하려고 했지만 디렉토리 구조도 제대로 잡지 않았고, 결국 하나의 버전에 바로바로 수정사항을 추가하는 식으로 개발하였다. 이번 프로젝트에서는 디렉토리 구조도 잘 짜고 네이밍도 제대로 하여 API 버전을 관리하고싶어 공부해보려고 한다.
참고사항: 백엔드는 springboot로 api를 작성하고 프론트에서 이를 받는 식으로 개발
Version 관리할 때 중요한 점
- URI가 지저분해지지 않도록 한다
- 캐시로 인해 지정한 값이 제대로 반영되지 않을 수 있다는 점을 유의
- API 개발자 문서를 꼼꼼하게 작성하여 지원해야한다
- 잘못된 헤더값은 지양한다
REST API 버전을 관리하는 4가지 방법
- URI Versioning
- Request Parameter Versioning
- MIME type Versioning
- Custom Header Versioning
URI Versioning
//http://localhost/v1/users
@GetMapping(value = "/v1/users")
- uri경로에 버전을 명시하는 방법
- Facebook, Twiteter, Airbnb 등이 이 방법을 사용
- API의 내부버전은 1.2.3 방식을 사용함
- [주버전.마이너버전.패치버전] 형식
- URI에 사용되는 버전은 주버전이며, API에 대한 주요 변경사항을 나타냄
- 마이너버전, 패치버전은 이전버전과 호환되는 업데이트를 위해 내부적으로 사용
- 장점
- 캐시키(URI)가 버전별로 변경되기 때문에 클라이언트가 리소스를 쉽게 캐시할 수 있음
- REST API의 새 버전이 release되면 캐시의 새 항목으로 인식
- 단점
- 주요 변경 사항을 도입하면 전체 API를 분기해야함
- 코드 기반에 상당한 공간을 차지
Request Parameter Versioning
//http://localhost/users?version=1
@GetMapping(value = "/users", params = "version=1")
- uri가 아닌 쿼리파라미터로 버전을 구분하는 방법
- amazon에서 사용
- 장점
- 구현 관점에서 API버전을 관리하기 간단함
- 최신 버전으로 기본 설정하기 쉬움
- 단점
- 요청을 적절한 API버전으로 라우팅하기 어려움
Content 협상을 통한 Versioning
//http://localhost/users
@GetMapping(value = "/users", produces = "application/vnd.company.appv1+json; version=1")
- 리소스 표현에 버전을 지정하는 방법
- 장점
- 전체 API를 버전화하는 대신 단일 리소스의 버전화를 통해 버전화를 세밀하게 제어가능
- 새 버전을 생성할 때 전체 애플리케이션을 분기할 필요가 없으므로 코드 베이스에 더 작은 공간 차지
- URI 경로를 통한 버전관리에 의해 도입된 URI 라우팅 규칙을 구현할 필요가 없다
- 단점
- URI버전 API보다 엑세스하기 어려움
- 미디어 유형이 있는 HTTP 헤더가 필요하면 브라우저를 사용하여 API를 테스트하기 어려움
- swagger와 같은 일부 도구는 경로는 같지만 Content-type이 다른 작업은 구분할 수 없다
- 클라이언트, 개발자 모두에게 높은 구현 비용 발생
Custom Header Versioning
//http://localhost/users
@GetMapping(value = "/users", headers = "X-API-VERSION=1")
- header에 X-API-VERSION으로 버전을 구분하는 방법
- 버전 정보가 속성으로 포함된 사용자 지정 헤더를 제공하여 버전을 지정
- 장점
- 버전 정보로 URI를 복잡하게 만들지 않음
- 단점
- 사용자 지정 헤더가 필요
4가지 방법 모두 장단점이 있는 것 같다.
spring 프로젝트를 개발하는 입장에서 2,3,4 번째 방법은 spring에서 /users 뒤에 파라미터로 분기할 수 없기 때문에 어려울 것 같고 분기관련한 공부가 더 필요할 것 같다.
처음으로 버전을 적용하는 상황이므로 가장 쉬운 첫 번째 방법을 사용하는 게 좋을 것 같다. swagger에서도 구분되니까 테스트도 훨씬 간편할 것 같다. 다음 프로젝트 등에서 request param을 사용하는 방법도 고려해봐야겠다.
// 구현방법 관련한 좋은 글
참고자료
https://sonseungha.tistory.com/581
https://www.xmatters.com/blog/blog-four-rest-api-versioning-strategies/
'Backend > Spring' 카테고리의 다른 글
[Spring] 클라이언트의 ip를 가져오는 방법(HttpServletRequest) (0) | 2023.08.13 |
---|---|
[Spring] jwt 로그아웃을 구현하는 방법 (0) | 2023.08.07 |
[Spring] 인프런 tdd 수업3 - 상품조회 기능 tdd (0) | 2023.07.15 |
[Spring] 인프런 tdd 수업2 - api테스트로 변환 (0) | 2023.07.15 |
[Spring] 인프런 tdd 수업1 - 간단한 service test 작성 (0) | 2023.07.15 |