Release 의 모든 것 (14장)
Release 의 모든 것 (14장) 의 내용 중, 인상적이었던 부분을 발췌 및 요약합니다.
버전 관리
버전을 올리는 경우에 우리가 호환성을 유지하는 추가 작업을 하는 것이 다른 팀에게 이전 비용을 강제로 전가하는 것보다 낫다.
호환되는 API 변경
TCP 규격에서 존 포스텔은 견고한 시스템을 구축하는 좋은 원칙을 제시했다.
자신이 하는 일에는 보수주의자가 되고, 외부를 수용할 때는 자유주의자가 되어야 한다.
이 원칙을 우리의 애플리케이션에서 적용해보자. API 란 소포트웨어 구성 요소 간 합의가 층층히 쌓인 것이다. 우리는 네트워크가 IP, TCP, UDP, DNS 로 구성되어 있다는 것을 합의한 것이다.
우리는 이런 계층 위에서 일곱 번째 계층의 애플리케이션을 만든다. 따라서 소비하는 서비스와 제공하는 서비스 간 다음과 같은 여러 합의를 공유하고 있다고 여겨야 한다.
- 연결 핸드셰이킹과 유지
- 요청 플헤임 처리
- 데이터 인코딩
- 메시지 구문
- 메시지 의미
- 권한 승인과 인증
이런 합의를 위반하는 협정을 경계해야 한다.
- 기존에 작동하던 네트워크 프로토콜을 거부
- 기존에 작동하던 요청 프레임이나 내용 인코딩을 거부
- 기존에 작동하던 요청 구문을 거부
- 기존에 작동하던 요청 경로(URL 이나 대기열)를 거부
- 필수 데이터를 요청에 추가
- 기존에 허용하던 요청의 선택적 정보를 거부
- 기존에 보장되던 응답의 정보를 제거
- 권한 등급 상향 요구
이전보다 더 많이 받아들일 수는 있어도 적게 받거나 더 많이 요구할 수는 없다. 이전보다 요구 항목이 적은 것은 괜찮다. 이전보다 더 많은 선택적인 정보를 받아들이는 것은 괜찮다. 이전보다 더 많은 정보를 반환하는 것은 괜찮다. 다음과 같은 변경은 안전하다.
- 기존에 요구하던 전체 매개변수의 부분 집합을 요구
- 기존에 받아들이던 전체 매개변수의 상위 집합을 받아들임
- 기존에 반환되던 값의 상위 집합을 반환
- 기존에 매개변수에 요구되었던 제약 조건의 부분 집합을 요구
다른 서비스가 규격에 맞개 개발되어 우리 서비스를 소화할 수 있도록 고려해야 한다. 경계 조건에 대한 생성형 테스트가 필요하여 규격 사이의 간극을 찾아야 한다.
이를 위해 외부 유입 테스트가 존재한다. 우리가 소비해야할 서비스에도 무작위로 생성형 테스트를 돌려봐야 한다. 외부 호출 테스트에 의해 내부 시스템이 테스트되어야 한다는 것이다. 누군간 이 테스트를 계약 테스트 라고 부른다. API 를 제공하는 측에서 준수하겠다고 약속하는 규격을 소비하는 측에서 테스트하기 때문이다.
호환성을 깨는 API 변경
URL 에 접두사나 질의 매개변수로 버전 식별 문자열을 추가하는 방법은 실무에서 가장 일반적으로 사용된다. 올바르게 작동하도록 경로를 분기하기 쉽다. 단점은 동일한 자원이지만 표현이 달라 다른 자원처럼 보인다는 것이다. GET 요청에 Accept 해더를 사용해서 희망하는 버전을 나타내거나, 애플리케이션 고유 헤더를 사용해서 희망하는 버전을 나타내도록 할 수도 있다. 이런 방법은 유연할 수 있지만, 소비하는 측에 공유되어야 할 암묵적 합의가 늘어난다는 점에서 제약이 있다.
결국 URL 에 뭔가를 넣는 쪽이 선호된다. URL 그 자체로 충분한 의미를 전달할 수 있고, 특별한 구성이 필요 없다. API 제공자로서 어떤 방법을 선택하든 기존 버전과 최신 버전을 모두 일정 기간 지원해야 한다. 서비스가 요청을 받으면, 컨트롤러 계층에서 최신 객체로 변환해서 최신 버전의 비즈니스 로직을 호출하는 방법을 추천한다.
다른 서비스의 버전 관리
요청이나 메시지를 받을 때 우리 애플리케이션에는 데이터 형식을 제어할 권한이 전혀 없다. 우리가 요청 규격에 신규 필드를 몇 개 추가한다고 모든 사람이 이를 따른 것이라고 여겨서는 안된다.
통합 테스트에서 흔하게 발생하는 실패는 다른 서비스를 호출하면서 지나치게 자세히 지정하려고 한다. 테스트는 호출이 잘 작동하는지 검증하지만, 호출하는 측에서 계약을 준수하는지 검증하지는 않는다.
우리가 만드는 소프트웨어는 냉소적인 태도를 유지해야 한다. 우리가 가장 믿는 서비스의 제공자가 언제나 무중단으로 배치한다고 주장하더라도 우리 서비스를 보호하는 것을 잊어서는 안된다.
결론
버전 관리는 본질적으로 지저분하고 복잡하다. 개인 관점이 아니라 전체 관점에서 생각해야 조직 전체를 위한 좋은 서비스를 만들 수 있을 것이다.