Feature Toggle은 애플리케이션 기능을 런타임에 켜고 끄는 메커니즘으로, 개발자가 코드를 변경하거나 재배포하지 않고도 기능 가용성을 관리할 수 있게 해줍니다. 조건부 컴파일(ifdef)과 달리 toggle은 런타임 수준에서 작동하며 동적으로 변경할 수 있습니다. Martin Fowler(2024)에 따르면, feature toggles는 trunk-based development와 지속적 전달의 핵심 요소입니다. Feature toggle은 팀에 릴리스 및 실험 관리의 유연성을 제공합니다.
핵심 요점
Feature Toggle은 새 기능의 코드를 조건문으로 감싸 구성 매개변수의 값을 확인하는 기술입니다. 매개변수가 true이면 새 기능이 활성화되고, false이면 이전 코드가 실행됩니다. 피처 플래그와의 주요 차이점은 toggle이 복잡한 타겟팅 규칙이나 트래픽 분산 없이 켜기/끄기 원칙으로 작동하는 이진 스위치라는 점입니다.
피처 토글은 새 기능 주변에 간단한 if-구문으로 구현됩니다. Toggle 값은 애플리케이션 구성—환경 변수, JSON 파일 또는 데이터베이스에 저장됩니다. 애플리케이션이 시작되면 구성을 로드하고 기능 가시성에 대한 결정을 내리는 데 사용합니다. 가장 간단한 경우, toggle 값을 변경하려면 애플리케이션을 다시 시작해야 하지만, 프로덕션 시스템에서는 일반적으로 외부 구성 서버 또는 API를 통해 핫 리로드를 지원합니다.
JavaScript(Node.js)에서 피처 토글 구현을 살펴보겠습니다. Toggle은 JSON 구성에 저장되며 서버가 시작될 때 로드됩니다. Middleware는 요청을 새 핸들러나 이전 핸들러로 라우팅하기 전에 toggle 값을 확인합니다. 이 구현을 통해 현재 API 버전을 손상시키지 않고 메인 코드 브랜치에 새 기능을 추가할 수 있습니다.
const config = require("./config.json");
const toggles = {
get(name) {
return config.features[name] ?? false;
},
isEnabled(name, context) {
const toggle = config.features[name];
if (!toggle) return false;
if (toggle.enabled === true) return true;
if (toggle.percentage && context.userId) {
return hashCode(context.userId) % 100 < toggle.percentage;
}
return false;
}
};
const app = express();
app.use("/api/checkout", (req, res, next) => {
if (toggles.isEnabled("new_checkout", req)) {
return newCheckoutHandler(req, res);
}
return legacyCheckoutHandler(req, res);
});
ThoughtWorks의 Pete Hodgson은 피처 토글을 수명과 목적에 따라 분류하여 세 가지 주요 유형을 제시합니다. Toggle 유형을 올바르게 식별하면 적절한 저장 메커니즘과 관리 프로세스를 선택하는 데 도움이 됩니다. 모바일 개발 맥락에서 각 유형을 살펴보겠습니다.
Business toggles는 가장 오래 지속되는 스위치입니다. 특정 사용자 범주(프리미엄 기능, 지역별 특성)만 사용할 수 있는 비즈니스 규칙을 관리합니다. 이러한 toggles는 수년간 지속될 수 있으며 일반적으로 이진 켜기/끄기보다 더 복잡한 로직을 가집니다. Release toggles는 완료되지 않은 기능을 숨기기 위한 임시 스위치입니다. 수명 주기는 며칠에서 몇 주까지입니다. 기능이 완료되면 release toggle이 코드에서 제거됩니다. 이 toggles는 trunk-based development의 기초이며, 개발자가 모든 기능이 완료될 때까지 기다리지 않고 메인 브랜치에 커밋할 수 있게 합니다.
Experiment toggles는 A/B 테스트 및 점진적 롤아웃에 사용됩니다. Release toggles와 달리 experiment toggles는 백분율 기반 사용자 분배 및 분석 시스템 통합을 지원합니다. Release toggles보다 더 오래(최대 몇 개월) 지속될 수 있지만, 실험 종료 후에는 제거해야 합니다. Infrastructure toggles는 인프라 변경(데이터베이스 마이그레이션, 새 API 제공업체 전환, 캐싱 알고리즘 변경)을 관리하기 위한 스위치입니다. 이러한 toggles는 전환 시 전체 서비스의 안정성에 영향을 미치므로 테스트에 특별한 주의가 필요합니다.
| Toggle 유형 | 기간 | 대상 | 예시 |
|---|---|---|---|
| Business | 개월-년 | 역할/지역별 | 프리미엄 기능 |
| Release | 일-주 | 개발자/QA | 미완성 화면 |
| Experiment | 주-개월 | 사용자 % | 인터페이스 A/B 테스트 |
| Infrastructure | 일-주 | 내부 | DB 마이그레이션 |
“feature toggle”과 “feature flag”라는 용어는 종종 상호 교환적으로 사용되지만, 이들 사이에는 개념적 차이가 있습니다. 이러한 차이를 이해하면 특정 작업에 적합한 도구를 선택하고 팀 내 혼란을 방지하는 데 도움이 됩니다. 각 접근 방식의 주요 차이점과 사용 사례를 살펴보겠습니다.
Feature toggle은 주로 기술적 메커니즘입니다: 애플리케이션 코드에 내장된 이진 스위치입니다. Toggle은 구성을 통해 관리되며 외부 인프라가 필요하지 않습니다. Feature flag는 더 넓은 개념으로, 관리 플랫폼(구성용 UI, 통합용 SDK, 사용 모니터링, 분석 및 감사)을 포함합니다. Flags는 복잡한 타겟팅 규칙(지역, 버전, 기기별), A/B 실험 및 자동 제거를 지원합니다. 피처 플래그는 피처 토글의 진화라고 할 수 있습니다: 팀은 간단한 구성 스위치로 시작하여 성장함에 따라 전문 플랫폼으로 이동합니다.
소규모 팀과 단일 서비스 또는 모노리스를 사용하는 프로젝트의 경우 간단한 구성 toggles로 충분합니다. 5~10명의 개발자와 동시에 1~2개의 활성 toggles가 있는 경우 외부 플랫폼은 과도합니다. 피처 플래그 플랫폼(LaunchDarkly, Unleash)은 활성 플래그 수가 20~30개를 초과하거나, 팀에 20명 이상의 개발자가 있거나, 다양한 사용자 세그먼트에 대한 세분화된 액세스 제어가 필요한 경우 필요해집니다. 클라이언트 업데이트에 며칠이 걸리는 모바일 애플리케이션의 경우, 피처 플래그 플랫폼은 추가 이점—새 버전을 게시하지 않고 애플리케이션 동작을 변경할 수 있는 기능—을 제공합니다.
피처 토글 관리 도구의 선택은 팀 규모, 기술 스택 및 보안 요구 사항에 따라 달라집니다. 간단한 구성 파일부터 엔터프라이즈급 관리 플랫폼까지, 오픈 소스 대안을 포함한 옵션을 살펴보겠습니다.
피처 토글은 CI/CD 파이프라인의 일급 시민이어야 합니다. 빌드 단계에서 파이프라인은 현재 스프린트에서 제거 예정인 모든 release toggles가 실제로 코드에서 제거되었는지 확인합니다. 테스트 단계에서는 다양한 toggle 조합으로 매트릭스 테스트가 실행됩니다. 배포 단계에서는 시스템이 프로덕션 환경과 toggle 구성을 자동으로 동기화합니다. PagerDuty 또는 Opsgenie와의 통합을 통해 stale toggles가 감지되거나 활성 toggles의 허용 수를 초과할 때 알림을 생성할 수 있습니다.
간단한 시나리오의 경우 변경 사항에 대한 코드 리뷰와 함께 Git의 JSON 구성으로 충분합니다. 더 고급 옵션은 Togglz(Java) 또는 Gofeature(Go)—toggle 관리를 위한 최소한의 UI를 추가하는 라이브러리입니다. 프로덕션 시스템의 경우 모든 언어에 대한 SDK와 활성화 전략 지원을 갖춘 Unleash(오픈 소스) 또는 내장 A/B 테스트가 있는 Flagsmith를 권장합니다. LaunchDarkly는 높은 감사 및 규정 준수 요구 사항이 있는 엔터프라이즈 프로젝트의 표준으로 남아 있습니다. 모바일 애플리케이션의 경우 모든 솔루션이 캐싱 및 오프라인 모드를 갖춘 네이티브 SDK를 제공합니다.
피처 토글은 양날의 검입니다. 관리 규율이 없으면 개발을 지연시키고 코드 복잡성을 증가시키는 기술 부채로 변합니다. CodeScene 연구(2024)에 따르면, 35~50%의 코드베이스에 stale toggles—롤아웃 완료 후에도 코드에 남아 있는 스위치—가 포함되어 있습니다. 이러한 부채를 방지하고 제거하기 위한 전략을 살펴보겠습니다.
피처 토글 제거 프로세스는 네 단계로 구성됩니다. 첫째: toggle이 100%의 사용자에 대해 활성화되었거나 0%에 대해 비활성화되었는지 확인합니다(어느 코드 브랜치를 유지할지에 따라 다름). 둘째: 코드에서 모든 조건부 toggle 확인을 제거하고 프로덕션 동작이 되어야 하는 브랜치만 남깁니다. 셋째: 스토리지 시스템(구성, 데이터베이스 또는 플랫폼)에서 toggle 정의를 제거합니다. 넷째: 제거가 기능을 손상시키지 않았는지 확인하는 테스트를 실행합니다. 각 toggle에는 스위치 생성 시 기록된 소유자와 계획된 제거 날짜가 있어야 합니다.
50개 이상의 스위치 규모에서는 수동 toggle 감사가 비효율적입니다. 자동화는 세 가지 원칙에 기반합니다: CI 확인(stale toggles가 병합 차단), 모니터링(각 toggle의 기간과 상태를 보여주는 대시보드), 알림(toggle이 N일 동안 변경되지 않은 경우 소유자에게 통지). 정적 코드 분석 도구(SonarQube, ESLint 플러그인)는 코드에서 항상 켜져 있거나 항상 꺼져 있는 toggles—stale toggle의 명확한 신호—를 감지할 수 있습니다. 최종 확인은 코드 리뷰이며, 리뷰어는 새 toggle이 실제로 필요한지, 이전 코드 브랜치가 제거될 것인지 확인해야 합니다.
package toggles
type Toggle struct {
Name string
Enabled bool
Owner string
CreatedAt time.Time
TTL time.Duration
}
type ToggleManager struct {
store map[string]*Toggle
}
func NewToggleManager() *ToggleManager {
return &ToggleManager{store: make(map[string]*Toggle)}
}
func (m *ToggleManager) IsEnabled(name string) bool {
t, ok := m.store[name]
if !ok {
return false
}
return t.Enabled
}
func (m *ToggleManager) GetStaleToggles() []string {
var stale []string
for name, t := range m.store {
if t.Enabled && time.Since(t.CreatedAt) > t.TTL {
stale = append(stale, name)
}
}
return stale
}
자주 묻는 질문
이 용어는 종종 상호 교환적으로 사용되지만, 기술적으로 feature toggle은 코드 내의 이진 스위치(구성 값을 확인하는 if-조건)입니다. Feature flag는 UI, SDK, 분석 및 복잡한 타겟팅 규칙을 포함한 관리 플랫폼을 포함하는 더 넓은 개념입니다. Toggle은 외부 인프라가 필요하지 않지만, flag는 일반적으로 필요합니다.
Release toggles는 롤아웃 완료 후 1~2주 이내에 제거해야 합니다. Experiment toggles는 A/B 테스트 종료 후 즉시 제거합니다. Business toggles는 정기적인 감사(분기별)가 필요합니다. 작업 추적기에 제거 작업 없이 PR이 새 toggle을 추가하는 경우 병합을 차단하는 CI 확인을 설정하는 것이 좋습니다.
네, 피처 토글은 모바일 개발에서 활발히 사용됩니다. 주요 도구는 Firebase Remote Config로, 애플리케이션의 새 버전을 게시하지 않고도 스위치를 동적으로 관리할 수 있습니다. 대안: iOS/Android용 LaunchDarkly SDK, Unleash SDK, REST API가 있는 사용자 정의 toggle 서버. 오프라인 모드에서 작동하려면 값 캐싱을 구현하는 것이 중요합니다.
주요 방법은 매트릭스 테스트입니다: toggle이 켜진 상태와 꺼진 상태 모두에서 모든 테스트를 실행합니다. N개의 toggles에 대해 완전한 매트릭스 테스트는 2^n번의 실행이 필요하므로, 실제로는 중요한 조합이 선택됩니다. 단위 테스트는 toggle 값을 모의해야 합니다. 통합 테스트는 특정 시나리오를 확인합니다. 예기치 않은 상호 작용을 감지하기 위해 무작위 toggle 조합으로 테스트를 실행하는 단계가 CI에 추가됩니다.
주요 위험: 1) stale toggles—두 브랜치(켜짐/꺼짐)가 있는 코드는 복잡해지고 유지 관리가 어려워집니다. 2) 테스트의 조합 복잡성—각 toggle이 상태 수를 두 배로 늘립니다. 3) 데드 코드—toggle이 영구적으로 활성화된 후에도 이전 브랜치가 코드에 남습니다. 4) 보안—액세스를 제어하는 스위치는 잘못된 구성 시 취약점을 만듭니다. 모든 위험은 규율과 자동화로 관리할 수 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.