개발/Spring Boot
Spring Boot 고급 시리즈 9편 – API 버전 없이 유연한 기능 확장: Feature Flag와 조건 분기 전략
B컷개발자
2025. 4. 22. 21:30
Spring Boot에서 Feature Flag와 조건 분기 전략을 활용해 API 버전 없이 기능을 점진적으로 확장하는 방법을 설명합니다. 실무 예제와 설계 원칙 포함.
Spring Boot 고급 시리즈 9편 – API 버전 없이 유연한 기능 확장: Feature Flag와 조건 분기 전략
API 기능을 개선하거나 새로운 기능을 추가할 때,
기존에는 /v1, /v2와 같이 버전을 나누는 방식이 일반적이었습니다.
그러나 모든 변경이 반드시 새로운 버전을 의미하진 않습니다.
이번 글에서는 버전을 늘리지 않고도 유연하게 기능을 제어할 수 있는
Feature Flag(기능 플래그) 전략과 조건 기반 분기 처리 방법을 다룹니다.
📌 1. 왜 버전 없이 기능을 분기해야 할까?
- API 경로 변경 없이 유지보수성 향상
- A/B 테스트, 점진적 기능 배포, 환경별 기능 제어 가능
- 운영 중에도 릴리즈 관리와 롤백이 빠름
- 클라이언트별로 유연한 기능 적용 로직 설계
🔧 2. Feature Flag란?
Feature Flag는 코드 내 특정 기능을 동적으로 켜고 끌 수 있는 스위치입니다.
✅ 주요 활용 사례
- 신규 기능 점진적 적용 (rollout)
- 특정 고객 그룹 대상 A/B 테스트
- 베타 기능 제공
- 긴급 상황에서 기능 빠른 비활성화
✅ 3. 조건 기반 분기 설계 전략
1️⃣ Controller 또는 Service 내 조건 분기 예시
@RestController
@RequiredArgsConstructor
public class RecommendationController {
private final RecommendationService recommendationService;
private final FeatureToggleService featureToggleService;
@GetMapping("/api/v1/recommend")
public ResponseEntity<?> getRecommendations(@RequestParam Long userId) {
if (featureToggleService.isEnabled("new-algo")) {
return ResponseEntity.ok(recommendationService.newAlgorithm(userId));
}
return ResponseEntity.ok(recommendationService.oldAlgorithm(userId));
}
}
✅ 단점 보완 전략
- 분기가 많아지면 서비스 코드가 오염됨
- → FeatureEvaluator, Strategy 패턴, Aspect를 통해 책임 분리 가능
🛠️ 4. Feature Toggle 구현 방법
1️⃣ application.yml 기반 구성 (간단)
features:
new-algo: true
beta-mode: false
@Component
@ConfigurationProperties(prefix = "features")
@Getter
@Setter
public class FeatureToggleConfig {
private Map<String, Boolean> toggles = new HashMap<>();
public boolean isEnabled(String key) {
return toggles.getOrDefault(key, false);
}
}
- 코드 변경 없이 YAML 수정만으로 기능 제어 가능
- 배포 자동화 시스템(CI/CD)와 연계하면 실시간 기능 토글 가능
2️⃣ DB 기반 플래그 관리 (운영 중 실시간 변경 가능)
@Entity
public class FeatureFlag {
@Id
private String name;
private boolean enabled;
}
public interface FeatureFlagRepository extends JpaRepository<FeatureFlag, String> {}
@Service
@RequiredArgsConstructor
public class FeatureToggleService {
private final FeatureFlagRepository repository;
public boolean isEnabled(String featureName) {
return repository.findById(featureName)
.map(FeatureFlag::isEnabled)
.orElse(false);
}
}
- 관리자 페이지에서 UI로 실시간 제어 가능
- 동시 다발적인 A/B 테스트 및 퍼센트 롤아웃 가능
🧠 실무 팁 – 클린한 기능 분기 설계
전략 설명
Strategy 패턴 | 기능 구현을 각각의 클래스로 분리 후 런타임 선택 |
AOP 기반 제어 | 기능 실행 전후 동작을 공통화 |
컨텍스트 분리 | 기능 조건을 FeatureContext로 캡슐화 |
조건 캐싱 | Redis 등에 캐싱하여 트래픽 대응 성능 확보 |
테스트 분리 | 각 분기별 테스트 케이스를 명확히 분리 |
🧪 예시: Feature Flag + Strategy 조합
public interface RecommendStrategy {
List<Product> recommend(Long userId);
}
@Component("new")
public class NewRecommendStrategy implements RecommendStrategy {
public List<Product> recommend(Long userId) {
return List.of(); // 신 알고리즘
}
}
@Component("old")
public class OldRecommendStrategy implements RecommendStrategy {
public List<Product> recommend(Long userId) {
return List.of(); // 기존 방식
}
}
@Service
@RequiredArgsConstructor
public class RecommendationService {
private final FeatureToggleService toggleService;
private final Map<String, RecommendStrategy> strategyMap;
public List<Product> recommend(Long userId) {
String key = toggleService.isEnabled("new-algo") ? "new" : "old";
return strategyMap.get(key).recommend(userId);
}
}
- 전략은 Bean으로 관리, Feature Flag는 key 결정만 담당
- 각 전략은 독립 테스트 가능
✅ 마무리 요약
항목 요약
목적 | API 버전 없이 유연하게 기능 제어 |
기술 | @Value, ConfigurationProperties, DB 기반 플래그, Strategy 패턴 |
추천 방식 | YAML 초기 구성 → 운영 중 DB/관리자 UI 기반 확장 |
설계 팁 | Controller 분기 지양, 서비스/전략 객체로 분리, 테스트 가능성 확보 |
사용 시점 | 실험적 기능, 단계적 배포, 긴급 대응 |
📌 다음 편 예고
Spring Boot 고급 시리즈 10편: 멀티 모듈 구조로 서비스 분리 – 실전 프로젝트 아키텍처 설계 전략
LIST