Feature Flag — це техніка розробки, при якій функціональність додатка вмикається або вимикається через умовні перемикачі в рантаймі, без розгортання нового коду. Замість традиційного підходу «закомітив — задеплоїв» feature flags дозволяють відокремити момент деплою від моменту ввімкнення функціональності. За даними LaunchDarkly (2024), команди, що використовують feature flags, скорочують час викатки нових функцій на 40%. Feature прапорці стали обов'язковим елементом CI/CD для сучасних мобільних та веб-додатків.
Головне
Feature Flag (фіча-прапорець, feature toggle) — це механізм, що дозволяє змінювати поведінку додатка без зміни коду. У найпростішому вигляді це умовна конструкція, яка перевіряє значення прапорця перед виконанням нової функціональності. Прапорець може зберігатися в конфігураційному файлі, базі даних або зовнішньому сервісі та змінюватися в реальному часі. Такий підхід дає командам можливість комітити незавершений код в основну гілку, не побоюючись, що він потрапить до користувачів до завершення розробки.
Основне призначення feature flags — розділення деплою та релізу. Деплой — це процес розміщення коду на сервері або в магазині додатків. Реліз — момент, коли функціональність стає доступною користувачеві. Без feature flags ці події збігаються: код виходить у production — користувачі його бачать. З feature flags код може бути задеплоєний у production тижнями раніше релізу, увімкнений для internal тестування або поступово rollout-итися на аудиторію. Це критично важливо для trunk-based development та continuous delivery.
Розглянемо базову реалізацію feature flag у мобільному додатку на Kotlin. Прапорець зберігається в Firebase Remote Config і завантажується при старті додатка. Залежно від значення прапорця показується старий або новий екран профілю. Така реалізація дозволяє релізити нову версію профілю без публікації оновлення в App Store — достатньо змінити значення в консолі Firebase.
class ProfileFeature {
private val flags = FeatureFlagProvider()
private val profileFlag = FlagKey("new_profile_enabled")
fun getProfileScreen(): Screen {
return if (flags.isEnabled(profileFlag)) {
NewProfileScreen()
} else {
LegacyProfileScreen()
}
}
}
class FeatureFlagProvider {
fun isEnabled(key: FlagKey): Boolean {
val raw = Firebase.remoteConfig.getString(key.name)
return raw.toBoolean()
}
}
Не всі feature flags однакові. Мартін Фаулер у своїй класифікації виділяє чотири типи прапорців, що різняться за метою використання, тривалістю життя та вимогами до управління. Правильна класифікація прапорців допомагає вибрати відповідну інфраструктуру та уникнути типових проблем.
Release toggles — найпоширеніший тип прапорців. Вони використовуються для приховування незавершеної функціональності в production. Розробник комітить код в основну гілку, загорнутий у прапорець, і поступово доробляє функціональність. Після завершення та тестування прапорець вмикається для всіх користувачів. Життєвий цикл такого прапорця — від кількох днів до двох тижнів. Після повного rollout прапорець видаляється з коду. Release toggles — основа trunk-based development.
Experiment toggles працюють у зв'язці з A/B тестуванням. Вони не просто вмикають/вимикають функціональність, а направляють користувача в одну з експериментальних груп. Такі прапорці часто підтримують складні правила таргетингу (за регіоном, версією OS, підпискою) та інтеграцію з системами аналітики. Ops toggles використовуються для операційного контролю — наприклад, вимкнення важкої функції при високому навантаженні або тимчасового вимкнення проблемного модуля без негайного деплою. Ops toggles мають бути максимально швидкими та надійними, оскільки від них залежить стабільність сервісу.
| Тип | Тривалість | Динаміка | Мета |
|---|---|---|---|
| Release | Дні-тижні | Постійний | Приховування незавершеного коду |
| Experiment | Дні-місяці | Динамічний | A/B тести та rollout |
| Ops | Години-дні | Динамічний | Операційний контроль |
| Permission | Місяці+ | Статичний | Розмежування доступу |
Управління feature flags — це окрема дисципліна, що включає зберігання, конфігурацію, моніторинг та аудит прапорців. Без системи управління прапорці перетворюються на неконтрольований технічний борг, що сповільнює розробку. Розглянемо ключові аспекти управління на прикладі production-системи.
Кожен feature flag проходить через чотири стадії: створення, використання, стабілізація та видалення. На стадії створення визначається ключ прапорця, тип та default-значення. У процесі використання команда моніторить, хто увімкнув прапорець, для якої аудиторії та з якою метою. Після стабілізації (функціональність повністю готова та перевірена) прапорець має бути видалений з коду. Процес видалення автоматизується через код-рев'ю: CI перевіряє, що всі прапорці, увімкнені для 100% користувачів, мають задачу на видалення.
Feature flags мають зберігатися централізовано, а не розмазуватися по конфігураційних файлах кожного сервісу. В ідеалі — виділений сервіс з UI (LaunchDarkly, Unleash). Мінімально прийнятний варіант — JSON-конфіг у репозиторії з code review на зміни. База даних для зберігання прапорців менш бажана, оскільки вимагає окремого інтерфейсу для управління. Кожен прапорець має мати власника (team або конкретного розробника), опис та термін життя (TTL). Регулярний audit stale flags — обов'язкова практика, автоматизована через CI задачу, що перевіряє прапорці без змін довше N днів.
Ринок інструментів для управління feature flags включає як комерційні платформи з повним циклом управління, так і open-source рішення для самостійного розгортання. Вибір інструменту залежить від масштабу команди, вимог до latency та compliance.
LaunchDarkly — лідер ринку з SDK для всіх популярних мов та платформ (iOS, Android, Web, Backend). Підтримує multi-environment, rule-based targeting, A/B експерименти та автоматичне видалення прапорців. Split — альтернатива з фокусом на enterprise-функції: role-based access, audit logs та compliance (SOC2, HIPAA). ConfigCat — більш легковаге та доступне рішення, що підходить для невеликих команд. Всі платформи надають SDK з кешуванням значень та мінімальним впливом на latency додатка.
Unleash — найбільш популярне open-source рішення з UI, API та SDK для всіх основних платформ. Підтримує стратегії активації (activation strategies), кастомні контексти та інтеграцію з Prometheus для моніторингу. Flagsmith — альтернатива з вбудованим A/B тестуванням та управлінням середовищами. Open-source рішення вимагають розгортання та підтримки інфраструктури, але дають повний контроль над даними та не мають ліцензійних обмежень. Для мобільних додатків обидва рішення надають native SDK з офлайн-кешуванням значень прапорців.
Feature flags — потужний інструмент, але без дисципліни вони створюють технічний борг та ускладнюють код. Мартін Фаулер та інженери LaunchDarkly сформулювали набір практик, які допомагають отримувати максимум користі від фіча-флагів без негативних наслідків. Розглянемо ключові рекомендації для production-систем.
Кожен feature flag, який не був видалений після завершення rollout, стає технічним боргом. Дослідження LaunchDarkly (2024) показало, що в середньому 30–40% прапорців залишаються в коді після того, як перестають бути потрібними. Рішення: впровадити правило «один прапорець — одна задача». При створенні прапорця в task tracker заводиться задача на його видалення з дедлайном. CI перевіряє, що немає прапорців, увімкнених на 100% довше 30 днів. Code review має перевіряти не тільки додавання, але й видалення прапорців.
Feature flags створюють комбінаторну складність для тестування: кожен прапорець подвоює кількість можливих станів додатка. Для управління цією складністю використовуються matrix-тести, що перевіряють всі комбінації прапорців, та feature flag toggling integration tests. У CI pipeline додається крок, який проганяє тести з різними комбінаціями значень прапорців. Для критичних прапорців (ops toggles) обов'язкові навантажувальні тести, що перевіряють, чи не викликає перемикання прапорця spike latency або помилок.
class FeatureFlagService:
def __init__(self, storage):
self.storage = storage
def is_enabled(self, flag_key, user_context):
flag = self.storage.get(flag_key)
if not flag:
return False
for rule in flag["rules"]:
if self._match_rule(rule, user_context):
return rule["value"]
return flag["default"]
def _match_rule(self, rule, context):
return (
rule["percentage"] > self._hash(context.user_id)
)
Часті запитання
Терміни часто використовуються як синоніми, але є нюанс: feature flag зазвичай позначає більш зрілу систему з централізованим управлінням, UI та SDK, а feature toggle — простий бінарний перемикач у коді. Мартін Фаулер використовує feature toggle як загальний термін, але в індустрії feature flag частіше асоціюється з комерційними платформами (LaunchDarkly, Split).
Вплив на продуктивність мінімальний при правильній реалізації. Кращі практики: кешувати значення прапорців у пам'яті з TTL 30–60 секунд, уникати синхронних HTTP-викликів при перевірці прапорця, використовувати SDK з локальним кешем та фоновою синхронізацією. За даними LaunchDarkly, p99 latency їх SDK становить менше 5 мс, що незначно для більшості додатків.
Feature flags не рекомендується використовувати для зміни бізнес-логіки в критичних фінансових операціях, де важливо точно знати, який код виконується. Також варто уникати прапорців для security-функцій (авторизація, шифрування) — вимкнення такого прапорця створює вразливість. Для інфраструктурних змін (зміна бази даних, міграція на нову архітектуру) feature flags корисні, але вимагають особливо ретельного тестування.
Основний підхід — matrix-тестування: прогін тестів з усіма комбінаціями прапорців. Для CI/CD це може бути занадто дорого (2^n комбінацій), тому на практиці тестуються всі прапорці окремо в обох станах (on/off), а для комбінацій — тільки критичні. Unit-тести мають mock-ати значення прапорця. Integration тести перевіряють конкретні сценарії з відомими значеннями прапорців. E2E тести покривають найбільш імовірні комбінації.
Процес видалення: 1) переконатися, що прапорець увімкнено на 100% для всіх користувачів і не використовується в experiment режимі; 2) видалити всі умовні перевірки прапорця з коду, залишивши тільки «нову» гілку; 3) видалити визначення прапорця з системи управління; 4) оновити тести, прибравши mock-и для видаленого прапорця. Рекомендується автоматизувати цей процес через CI: прапорці без змін довше N днів позначаються як stale та вимагають підтвердження на видалення.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також