안정성 수준
고친 사람 github-actions[bot]
안정성 수준은 라이브러리나 서비스의 기능이 앞으로 얼마나 바뀔 수 있는지를 쓰는 쪽에게 미리 알려 줍니다. 쓰는 쪽은 이 표시를 보고 그 기능에 얼마나 기대도 되는지 가늠합니다. 내는 쪽은 아직 다듬는 중인 기능도 이 표시를 붙여 일찍 내놓을 수 있습니다.
쉽고 빠른 이해
무슨 일을 하는 물건인가 — 기능마다 「아직 바뀔 수 있음」이나 「깨지 않고 오래 둠」 같은 꼬리표를 붙여 알리는 일입니다. 새로 넣은 함수에 「베타」를 붙여 내놓으면 써 봐도 된다는 뜻입니다. 대신 모양이 바뀔 수 있습니다.
왜 이렇게 하나 — 쓰는 쪽은 공개된 기능이면 계속 같은 방식으로 돌 거라고 믿고 코드를 짭니다. 꼬리표가 없으면 내는 쪽은 덜 다듬은 기능을 내놓는 순간 더는 고칠 수 없게 됩니다. 그렇다고 다 굳을 때까지 숨겨 두면 써 본 사람의 의견을 못 받습니다. 그래서 모양이 덜 굳은 기능을 일찍 내놓을 때 이 꼬리표를 붙입니다.
어떻게 도나
- 새 기능을 「알파」나 「베타」처럼 바뀔 수 있는 단계로 내놓습니다
- 써 본 사람들의 의견을 받아 모양을 고칩니다
- 더 고칠 것이 없으면 「안정」으로 올립니다. 그때부터는 깨지 않겠다고 약속합니다
- 없앨 때는 「사용 중단」을 먼저 붙여 옮겨 갈 시간을 줍니다
대가 — 내는 쪽은 단계마다 한 약속을 지켜야 합니다. 베타에 오래 머문 기능은 이미 많은 사람이 기대고 있어서 꼬리표와 달리 바꾸기 어려워집니다. 쓰는 쪽은 알파나 베타 기능이 바뀌면 코드를 고쳐야 합니다. 그래서 오래 돌릴 프로덕션 코드에는 주로 안정 단계의 기능을 고릅니다.
상세
식당 메뉴판 한쪽에 「이번 달 시범 메뉴」라는 칸이 있다고 해 봅시다. 손님은 그 칸의 음식이 다음 달에 빠지거나 맛이 바뀔 수 있다는 것을 압니다. 늘 먹던 정규 메뉴는 그런 걱정 없이 시킵니다. 식당은 시범 칸 덕분에 새 음식을 일찍 내보이고 손님의 반응을 봅니다.
API(Application Programming Interface)는 한 프로그램이 다른 프로그램의 기능을 부를 때 지키는 약속입니다. 라이브러리가 내놓는 함수나 웹 서비스가 받는 요청 주소가 API 입니다. 쓰는 쪽은 이 약속에 맞춰 자기 코드를 짭니다.
안정성 수준은 API 의 각 부분에 「앞으로 얼마나 바뀔 수 있는가」를 단계로 매겨 붙인 표시입니다. 결제 라이브러리가 기존 결제 함수에는 「안정」을, 새로 넣은 분할 결제 함수에는 「베타」를 붙였다고 해 봅시다. 쓰는 쪽은 앞 함수에는 마음 놓고 기댑니다. 뒤 함수는 바뀔 수 있다는 것을 알고 씁니다.
꼬리표 없이 공개한 기능
안정성 수준이 왜 필요한지는 표시가 없는 상황을 떠올리면 드러납니다. 쓰는 쪽과 내는 쪽이 저마다 무엇을 바라는지부터 보겠습니다.
쓰는 쪽은 공개된 API 가 계속 같은 방식으로 돌 거라고 기대합니다. 그 기대를 믿고 코드를 짜서 프로덕션에 올립니다. 프로덕션은 실제 사용자가 쓰는 운영 환경입니다.
API 가 바뀌어도 기존 코드가 고치지 않은 채 계속 도는 성질을 하위 호환이라고 부릅니다. 쓰는 쪽이 바라는 것이 바로 이 성질입니다.
이 성질을 깨는 변경은 하위 비호환 변경이라고 부릅니다. 함수 이름을 바꾸거나 응답에서 값 하나를 빼는 것이 그 예입니다.
내는 쪽의 사정은 다릅니다. 새 기능의 모양은 써 본 사람의 의견을 들어야 굳습니다. 처음 정한 이름과 인자가 어긋났다는 것은 대개 내놓은 뒤에야 압니다.
표시가 없으면 내는 쪽은 둘 중 하나를 고르게 됩니다. 다 굳을 때까지 내놓지 않으면 의견을 못 받습니다. 일찍 내놓으면 모양을 고칠 때마다 쓰는 쪽 코드를 깹니다. 안정성 수준은 「이 부분은 아직 바뀔 수 있다」고 미리 말해 두어 이 둘 사이에 길을 냅니다.
단계의 이름과 뜻
단계를 몇 개로 나누고 어떻게 부를지는 프로젝트마다 다릅니다. 그래도 많은 프로젝트가 비슷한 넷을 씁니다. 이름이 달라도 재는 축은 하나입니다. 얼마나 바뀔 수 있는가입니다.
| 단계 | 흔한 다른 이름 | 바뀔 수 있는 정도 | 쓰는 쪽에 맞는 쓰임 |
|---|---|---|---|
| 알파 | 실험 · experimental | 예고 없이 바뀌거나 사라질 수 있다 | 시험 삼아 써 보고 의견을 낸다 |
| 베타 | 미리 보기 · preview | 큰 틀은 섰지만 세부가 바뀔 수 있다 | 바뀌면 고칠 각오로 쓴다 |
| 안정 | 정식 · stable | 하위 비호환 변경을 하지 않는다 | 프로덕션 코드가 기댄다 |
| 사용 중단 | deprecated | 아직 돌지만 곧 없어진다 | 대신할 기능으로 옮긴다 |
표의 줄 순서는 한 기능이 거쳐 가는 순서입니다. 알파에서 안정으로 갈수록 약속이 굳어집니다. 사용 중단은 그 끝을 향하는 단계입니다. 안정 단계를 GA(General Availability, 일반 공개)라고 부르는 곳도 많습니다. 누구나 정식으로 써도 된다는 뜻입니다.
마지막 줄의 사용 중단(deprecation)은 곧 없앨 기능에 미리 붙이는 표시입니다. 표시가 붙은 기능은 아직 돕니다. 부를 때 경고가 나거나 문서에 대신 쓸 기능이 적힙니다.
단계가 옮겨 가는 길
한 기능은 보통 한 단계에 머물지 않습니다. 다듬어지면 다음 단계로 넘어갑니다. 수명이 다하면 사용 중단을 거쳐 사라집니다. 그 흐름을 그림으로 보겠습니다.
stateDiagram-v2
state "알파" as Alpha
state "베타" as Beta
state "안정" as Stable
state "사용 중단" as Deprecated
state "제거" as Removed
[*] --> Alpha
Alpha --> Beta: 큰 틀이 섰다
Beta --> Stable: 더 고칠 것이 없다
Stable --> Deprecated: 대신할 기능이 나왔다
Deprecated --> Removed: 옮겨 갈 시간이 끝났다
Alpha --> Removed: 접기로 했다
Beta --> Removed: 접기로 했다
알파에서 안정으로 가는 길은 한 방향입니다. 안정이 된 기능은 보통 베타로 되돌리지 않습니다. 쓰는 쪽이 이미 깨지지 않는다는 약속을 믿고 코드를 짰기 때문입니다.
알파나 베타의 기능은 사용 중단을 거치지 않고 바로 제거하기도 합니다. 처음부터 사라질 수 있다고 밝혀 둔 단계라서 그렇습니다. 안정 단계의 기능은 사용 중단을 붙여 옮겨 갈 시간을 준 뒤에 제거합니다.
단계를 표시하는 방법
안정성 수준은 쓰는 쪽 눈에 띄어야 쓸모가 있습니다. 어디에 적느냐는 API 의 생김새에 따라 갈립니다. 흔한 방법 넷을 차례로 보겠습니다.
첫째는 버전 번호에 적는 방법입니다. 시맨틱 버저닝(Semantic Versioning)은 버전을 2.3.1 처럼 점으로 나뉜 세 칸으로 적는 규칙입니다. 칸마다 언제 올리는지를 정해 두어서 번호만 보고 무엇이 바뀌었는지 짐작하게 합니다.
세 칸 중 첫 칸이 메이저 버전입니다. 2.3.1 의 2 가 그것입니다. 이 칸이 오르면 기존 코드가 깨질 수 있다는 신호입니다. 그래서 안정 단계의 기능을 깨지 않고는 못 고칠 때 이 칸을 올려 냅니다.
이 규칙은 번호 뒤에 -alpha.1 이나 -beta.2 같은 꼬리를 붙이게 해 줍니다. 꼬리가 붙은 버전을 프리릴리스라고 부릅니다. 정식 버전이 나오기 전에 내놓는 버전이라는 뜻입니다. 같은 기능이 정식 버전이 되기까지 번호는 이렇게 바뀝니다.
1.4.0-alpha.1 // 알파 · 다 바뀐다
1.4.0-beta.2 // 베타 · 세부만
1.4.0 // 안정 · 안 깬다
꼬리가 붙은 버전은 꼬리 없는 1.4.0 보다 낮은 버전으로 칩니다. 꼬리가 사라진 버전이 안정 단계가 된 버전입니다.
시맨틱 버저닝은 첫 칸이 0 인 버전 전체도 비슷하게 봅니다. 0.y.z 꼴의 버전은 아직 처음 만드는 단계라서 무엇이든 바뀔 수 있다고 둡니다. 라이브러리 전체를 알파나 베타에 둔 셈입니다.
둘째는 웹 API 의 주소에 적는 방법입니다. 웹 API 는 버전을 주소 앞부분에 넣는 일이 많습니다. 거기에 단계를 함께 넣어 /v2beta/orders 처럼 씁니다. 쓰는 쪽은 주소만 보고 베타 기능을 부르고 있다는 것을 압니다.
셋째는 코드와 문서에 표시를 다는 방법입니다. 함수나 클래스 위에 사용 중단 같은 단계를 적어 두면 개발 도구가 그 표시를 읽어 경고를 띄울 수 있습니다. 자바의 @Deprecated 가 그런 표시입니다. 이 표시가 붙은 메서드를 부르면 컴파일러가 경고를 냅니다.
넷째는 기능을 기본으로 꺼 두는 방법입니다. 알파 기능은 쓰는 쪽이 설정으로 켜야만 돌게 해 둡니다. 켜는 사람은 바뀔 수 있다는 것을 알고 켭니다. 이렇게 설정으로 기능을 켜고 끄는 장치를 기능 플래그라고 부릅니다.
베타 기능을 쓸 때의 판단
안정성 수준은 쓰는 쪽에게 「쓰지 마라」가 아니라 「알고 써라」를 말합니다. 어느 단계의 기능을 어디에 쓸지는 그 기능이 바뀌었을 때 고칠 일이 얼마나 되는지로 가늠합니다.
오래 돌릴 프로덕션 코드가 알파 기능에 기대면, 그 기능이 바뀔 때마다 코드를 고쳐야 합니다. 그래서 프로덕션에는 안정 단계의 기능을 고르는 일이 많습니다. 알파 기능은 시험용 프로젝트에서 먼저 써 보고 의견을 냅니다.
베타 기능이 꼭 필요하면 그 기능을 부르는 코드를 한 군데로 모읍니다. 여러 곳에서 직접 부르지 않고, 감싸는 함수 하나를 거쳐 부르게 하는 식입니다. 그러면 베타 기능이 바뀌어도 그 함수 하나만 고치면 됩니다.
받아 쓰는 라이브러리의 버전을 어떻게 적느냐도 따져 봅니다. 쓰는 쪽은 빌드 설정에 어느 라이브러리의 어느 버전을 받을지 적어 둡니다. 적는 방법은 크게 둘입니다.
pay-lib = 1.4.0 // 고정 · 이것만
pay-lib >= 1.4, < 2.0 // 범위 · 새 것도
첫 줄은 버전 하나만 적은 것입니다. 이렇게 버전을 하나로 박아 두는 것을 버전 고정이라고 부릅니다. 빌드를 몇 번 다시 해도 같은 버전이 들어옵니다.
둘째 줄은 버전 범위를 적은 것입니다. 범위 안의 새 버전이 나오면 다음 빌드에 저절로 들어옵니다. 앞의 결제 라이브러리가 1.5.0 에서 베타였던 분할 결제 함수의 모양을 바꿨다고 해 봅시다. 아무도 손대지 않은 빌드가 어느 날 깨집니다. 그래서 베타 기능에 기대는 코드는 버전을 고정해 둡니다.
내는 쪽이 지는 약속의 무게
안정성 수준은 내는 쪽에게도 짐을 지웁니다. 단계를 붙인 순간부터 그 단계에서 한 약속을 지켜야 하기 때문입니다. 이 짐이 커지는 경우 둘을 보겠습니다.
베타에 오래 머문 기능이 첫째입니다. 쓰는 사람이 많아지면 꼬리표가 베타여도 바꾸기 어렵습니다. 바꾸는 순간 그 많은 코드가 한꺼번에 깨지기 때문입니다. 꼬리표는 「바꿀 수 있다」고 말합니다. 그래도 쓰는 쪽의 규모가 바꿀 수 있는 폭을 줄입니다.
안정에 너무 일찍 올린 기능이 둘째입니다. 어긋난 모양을 오래 끌고 가야 합니다. 고치려면 사용 중단과 메이저 버전을 거쳐야 해서 여러 버전에 걸친 일이 됩니다. 그래서 안정으로 올리기 전에 베타에서 충분히 써 보게 합니다.
안정성 수준은 도구가 검사해 주는 사실이 아니라 내는 쪽의 선언입니다. 「안정」이라고 적어 놓고 깨지는 변경을 넣는 실수도 생깁니다. 그래서 쓰는 쪽은 버전을 올리기 전에 버전마다 바뀐 것을 적은 변경 로그를 함께 읽습니다.
관련 항목
안정성 수준이 나누는 단계
알파 버전 · 베타 버전 · 정식 출시 · 실험 기능 · 프리릴리스 · 릴리스 후보
안정성 수준이 지키려는 호환성 약속
하위 호환 · 하위 비호환 변경 · 브레이킹 체인지 · 공개 API · API 계약 · 상위 호환
안정성 수준을 싣는 버전 규칙
시맨틱 버저닝 · 버저닝 · 메이저 버전 · 마이너 릴리스 · 패치 릴리스 · API 버전 관리
기능을 거두는 단계와 기간
사용 중단 · 사용 중단 경고 · 폐기 예고 · 유예 기간 · 지원 종료 · 장기 지원
단계를 알리고 켜고 끄는 장치
기능 플래그 · 어노테이션 · 변경 로그 · 릴리스 노트 · API 문서
베타 기능을 쓰는 쪽의 대비 수단
어댑터 패턴 · 버전 고정 · 락 파일 · 의존성 관리 · 버전 범위 · 프로덕션 환경
안정성 수준이 속하는 상위 분야
다른 이름: stability level · API stability level · 안정성 단계 · API 안정성 수준 · 안정성 등급