Skip to content

Latest commit

 

History

History
46 lines (33 loc) · 2.47 KB

File metadata and controls

46 lines (33 loc) · 2.47 KB

API 버전 정책

관련 이슈: #44

결정 — 헤더로 협상한다

방식 판단
경로 (/api/v1/facilities) 채택하지 않음
헤더 (X-API-Version: 1) 채택

경로 방식을 쓰지 않는 이유:

  • 프런트가 부르는 모든 경로와 SecurityConfig 의 인가 규칙이 버전 없는 경로로 짜여 있다. 경로에 버전을 넣으면 인가 규칙을 두 벌로 유지해야 하고, 한쪽만 고치면 그대로 구멍이 된다.
  • 버전이 갈리는 건 보통 일부 API 뿐이다. 헤더 방식은 바뀐 API 만 새 버전 처리를 두면 된다.

예전 BaseController 의 @RequestMapping("/api/v1") 은 하위 컨트롤러가 전부 덮어써서 어떤 경로에도 적용된 적이 없다. 오해만 낳아 지웠다.

규칙

요청 처리 응답 헤더
헤더 없음 현재 버전(1) X-API-Version: 1
X-API-Version: 1 또는 v1 1 X-API-Version: 1
지원하지 않는 값 (2, abc …) 400 API_VERSION_UNSUPPORTED X-API-Version: 1
  • 헤더가 없으면 현재 버전이다. 지금 클라이언트는 아무것도 바꾸지 않아도 된다.
  • 모르는 버전을 400 으로 거절하는 이유: 다른 버전을 기대한 클라이언트에게 조용히 현재 버전을 주면 필드가 어긋나도 알아채지 못한다. 이 프로젝트에서 실제로 여러 번 겪은 실패 방식이다.
  • 구현: core/web/ApiVersionFilter. CORS 허용·노출 헤더에 포함돼 브라우저에서도 읽을 수 있다.
  • Swagger 의 모든 API 에 선택 헤더로 표시된다.

호환되지 않는 변경을 할 때

필드 삭제·이름 변경·타입 변경·필수값 추가가 여기에 해당한다. 필드 추가는 호환 변경이다.

  1. ApiVersionFilter.SUPPORTED 에 새 버전을 추가한다 (CURRENT 는 아직 올리지 않는다).
  2. 바뀌는 API 에서 요청 속성 ApiVersionFilter.REQUEST_ATTRIBUTE 로 버전을 보고 응답을 가른다.
  3. 프런트가 새 버전 헤더를 보내도록 배포한다.
  4. 옛 버전 응답에 Deprecation·Sunset 헤더를 붙여 종료일을 알린다.
  5. 종료일이 지나면 옛 버전을 SUPPORTED 에서 빼고 CURRENT 를 올린다.

가능하면 1~5 대신 새 필드를 추가하고 옛 필드를 유지하는 호환 변경을 먼저 검토한다. (예: 정책 검색 응답의 totalCount 는 totalElements 를 추가한 뒤에도 남겨 두었다.)