Feature Flag, uygulama işlevselliğinin yeni kod dağıtmadan çalışma zamanında koşullu anahtarlar aracılığıyla etkinleştirildiği veya devre dışı bırakıldığı bir geliştirme tekniğidir. Geleneksel “commit — deploy” yaklaşımı yerine, feature flag'ler dağıtım anını işlevsellik etkinleştirme anından ayırmaya olanak tanır. LaunchDarkly (2024)'e göre, feature flag kullanan ekipler yeni özelliklerin çıkış süresini %40 oranında azaltır. Feature flag'ler modern mobil ve web uygulamaları için CI/CD'nin temel bir öğesi haline gelmiştir.
Önemli noktalar
Feature Flag (özellik toggle'ı), kodu değiştirmeden uygulama davranışını değiştirmeye izin veren bir mekanizmadır. En basit haliyle, yeni işlevselliği yürütmeden önce flag değerini kontrol eden koşullu bir yapıdır. Flag, bir yapılandırma dosyasında, veritabanında veya harici bir hizmette saklanabilir ve gerçek zamanlı olarak değiştirilebilir. Bu yaklaşım, ekiplere geliştirme tamamlanmadan önce kullanıcılara ulaşma korkusu olmadan tamamlanmamış kodu ana dala gönderme yeteneği verir.
Feature flag'lerin temel amacı, dağıtımı yayından ayırmaktır. Dağıtım, kodu bir sunucuya veya uygulama mağazasına yerleştirme sürecidir. Yayın, işlevselliğin kullanıcı için kullanılabilir hale geldiği andır. Feature flag'ler olmadan, bu olaylar çakışır: kod üretime girer — kullanıcılar onu görür. Feature flag'ler ile kod, yayından haftalar önce üretime dağıtılabilir, dahili testler için etkinleştirilebilir veya kademeli olarak kullanıcılara sunulabilir. Bu, trunk-based development ve sürekli teslimat için kritik öneme sahiptir.
Bir mobil Kotlin uygulamasında temel bir feature flag uygulaması düşünün. Flag, Firebase Remote Config'te saklanır ve uygulama başladığında yüklenir. Flag değerine bağlı olarak eski veya yeni profil ekranı gösterilir. Bu uygulama, App Store'da bir güncelleme yayınlamadan yeni bir profil sürümü çıkarmaya olanak tanır — sadece Firebase konsolunda değeri değiştirin.
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()
}
}
Tüm feature flag'ler aynı değildir. Martin Fowler'ın sınıflandırması, kullanım amacı, yaşam süresi ve yönetim gereksinimleri açısından farklılık gösteren dört tür flag belirler. Doğru flag sınıflandırması, uygun altyapıyı seçmeye ve yaygın sorunlardan kaçınmaya yardımcı olur.
Release toggles en yaygın flag türüdür. Üretimde tamamlanmamış işlevselliği gizlemek için kullanılırlar. Geliştirici, bir flag içine sarılmış kodu ana dala gönderir ve işlevselliği kademeli olarak tamamlar. Tamamlama ve testlerden sonra flag tüm kullanıcılar için etkinleştirilir. Böyle bir flag'in yaşam döngüsü birkaç günden iki haftaya kadar değişir. Tam dağıtımdan sonra flag koddan kaldırılır. Release toggles, trunk-based development'in temelidir.
Experiment toggles A/B testleriyle birlikte çalışır. Sadece işlevselliği açıp kapatmakla kalmaz, kullanıcıyı deneysel gruplardan birine yönlendirir. Bu flag'ler genellikle karmaşık hedefleme kurallarını (bölgeye, işletim sistemi sürümüne, aboneliğe göre) ve analitik sistemlerle entegrasyonu destekler. Ops toggles operasyonel kontrol için kullanılır — örneğin, yüksek yük altında ağır bir özelliği devre dışı bırakmak veya hemen dağıtım yapmadan sorunlu bir modülü geçici olarak kapatmak. Ops toggles mümkün olduğunca hızlı ve güvenilir olmalıdır, çünkü hizmetin kararlılığı onlara bağlıdır.
| Tür | Süre | Dinamik | Amaç |
|---|---|---|---|
| Release | Günler-haftalar | Statik | Tamamlanmamış kodu gizleme |
| Experiment | Günler-aylar | Dinamik | A/B testleri ve dağıtım |
| Ops | Saatler-günler | Dinamik | Operasyonel kontrol |
| Permission | Aylar+ | Statik | Erişim kontrolü |
Feature flag yönetimi, flag'lerin depolanması, yapılandırılması, izlenmesi ve denetlenmesini içeren ayrı bir disiplindir. Bir yönetim sistemi olmadan, flag'ler kontrol edilemez teknik borca dönüşür ve geliştirmeyi yavaşlatır. Bir üretim sistemini örnek alarak yönetimin temel yönlerini inceleyelim.
Her feature flag dört aşamadan geçer: oluşturma, kullanım, stabilizasyon ve kaldırma. Oluşturma aşamasında, flag anahtarı, türü ve varsayılan değeri tanımlanır. Kullanım sırasında, ekip flag'i kimin, hangi kitle için ve hangi amaçla etkinleştirdiğini izler. Stabilizasyondan sonra (işlevsellik tamamen hazır ve test edilmiş), flag koddan kaldırılmalıdır. Kaldırma süreci kod incelemesi yoluyla otomatikleştirilir: CI, %100 kullanıcı için etkinleştirilen tüm flag'lerin bir kaldırma görevi olduğunu kontrol eder.
Feature flag'ler, her hizmetin yapılandırma dosyalarına dağıtılmak yerine merkezi olarak depolanmalıdır. İdeal olarak — kullanıcı arayüzlü özel bir hizmet (LaunchDarkly, Unleash). Kabul edilebilir minimum seçenek, değişiklikler için kod incelemesi olan bir depodaki JSON yapılandırmasıdır. Flag'leri depolamak için bir veritabanı, ayrı bir yönetim arayüzü gerektirdiğinden daha az tercih edilir. Her flag'in bir sahibi (ekip veya belirli bir geliştirici), bir açıklaması ve bir yaşam süresi (TTL) olmalıdır. Eski flag'lerin düzenli denetimi zorunlu bir uygulamadır ve N günden uzun süredir değişmeyen flag'leri kontrol eden bir CI görevi aracılığıyla otomatikleştirilir.
Feature flag yönetim araçları pazarı, hem tam yönetim döngüsüne sahip ticari platformları hem de kendi kendine dağıtım için açık kaynak çözümlerini içerir. Araç seçimi, ekip büyüklüğüne, gecikme gereksinimlerine ve uyumluluğa bağlıdır.
LaunchDarkly, tüm popüler diller ve platformlar (iOS, Android, Web, Backend) için SDK'larıyla pazar lideridir. Çoklu ortam, kural tabanlı hedefleme, A/B deneyleri ve otomatik flag kaldırmayı destekler. Split, kurumsal özelliklere odaklanan bir alternatiftir: rol tabanlı erişim, denetim günlükleri ve uyumluluk (SOC2, HIPAA). ConfigCat, küçük ekipler için uygun, daha hafif ve uygun fiyatlı bir çözümdür. Tüm platformlar, değer önbellekleme ve uygulama gecikmesi üzerinde minimum etki ile SDK'lar sağlar.
Unleash, kullanıcı arayüzü, API ve tüm büyük platformlar için SDK'lar ile en popüler açık kaynak çözümdür. Etkinleştirme stratejilerini, özel bağlamları ve izleme için Prometheus ile entegrasyonu destekler. Flagsmith, yerleşik A/B testi ve ortam yönetimi ile bir alternatiftir. Açık kaynak çözümler, altyapı dağıtımı ve bakımı gerektirir, ancak veriler üzerinde tam kontrol sağlar ve lisans kısıtlaması yoktur. Mobil uygulamalar için, her iki çözüm de çevrimdışı flag değeri önbellekleme ile yerel SDK'lar sağlar.
Feature flag'ler güçlü bir araçtır, ancak disiplin olmadan teknik borç yaratır ve kodu karmaşıklaştırır. Martin Fowler ve LaunchDarkly mühendisleri, olumsuz sonuçlar olmadan feature flag'lerden maksimum fayda sağlamaya yardımcı olan bir dizi uygulama formüle etmiştir. Üretim sistemleri için temel önerileri inceleyelim.
Dağıtım tamamlandıktan sonra kaldırılmayan her feature flag teknik borç haline gelir. LaunchDarkly (2024) tarafından yapılan bir araştırma, ortalama olarak flag'lerin %30–40'ının artık gerekli olmadıktan sonra kodda kaldığını göstermiştir. Çözüm: “bir flag — bir görev” kuralını uygulayın. Bir flag oluştururken, görev takipçisinde son tarihli bir kaldırma görevi oluşturulur. CI, 30 günden uzun süredir %100 etkinleştirilmiş flag olmadığını kontrol eder. Kod incelemesi yalnızca flag eklemeyi değil, aynı zamanda kaldırmayı da kontrol etmelidir.
Feature flag'ler test için kombinatoryal karmaşıklık yaratır: her flag, olası uygulama durumlarının sayısını ikiye katlar. Bu karmaşıklığı yönetmek için, tüm flag kombinasyonlarını kontrol eden matris testleri ve flag geçiş entegrasyon testleri kullanılır. CI pipeline'ına farklı flag değer kombinasyonlarıyla testler çalıştıran bir adım eklenir. Kritik flag'ler (ops toggles) için, flag geçişinin gecikme artışına veya hatalara neden olmadığını doğrulamak için yük testleri zorunludur.
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)
)
Sıkça sorulan sorular
Terimler genellikle birbirinin yerine kullanılır, ancak bir nüans vardır: Feature flag genellikle merkezi yönetim, kullanıcı arayüzü ve SDK'lar ile daha olgun bir sistemi ifade ederken, feature toggle kodda basit bir ikili anahtardır. Martin Fowler, feature toggle'ı genel bir terim olarak kullanır, ancak endüstride feature flag daha çok ticari platformlarla (LaunchDarkly, Split) ilişkilendirilir.
Doğru uygulama ile performans etkisi minimumdur. En iyi uygulamalar: flag değerlerini 30–60 saniye TTL ile bellekte önbelleğe alın, bir flag kontrol ederken senkron HTTP çağrılarından kaçının, yerel önbellek ve arka plan senkronizasyonu olan SDK'lar kullanın. LaunchDarkly'ye göre, SDK'larının p99 gecikmesi 5 ms'nin altındadır ve bu çoğu uygulama için ihmal edilebilir düzeydedir.
Feature flag'ler, hangi kodun çalıştığını tam olarak bilmenin önemli olduğu kritik finansal işlemlerde iş mantığını değiştirmek için önerilmez. Ayrıca güvenlik işlevleri (yetkilendirme, şifreleme) için flag'lerden kaçının — böyle bir flag'i devre dışı bırakmak bir güvenlik açığı oluşturur. Altyapı değişiklikleri (veritabanı geçişi, yeni mimariye geçiş) için feature flag'ler faydalıdır ancak özellikle kapsamlı test gerektirir.
Ana yaklaşım matris testidir: tüm flag kombinasyonlarıyla testler çalıştırmak. CI/CD için bu çok pahalı olabilir (2^n kombinasyon), bu nedenle pratikte tüm flag'ler ayrı ayrı her iki durumda (açık/kapalı) test edilir ve yalnızca kritik kombinasyonlar test edilir. Birim testleri flag değerini taklit etmelidir. Entegrasyon testleri, bilinen flag değerleriyle belirli senaryoları kontrol eder. E2E testleri en olası kombinasyonları kapsar.
Kaldırma süreci: 1) flag'in tüm kullanıcılar için %100 etkinleştirildiğinden ve deney modunda kullanılmadığından emin olun; 2) koddan flag'in tüm koşullu kontrollerini kaldırın, yalnızca “yeni” dalı bırakın; 3) yönetim sisteminden flag tanımını kaldırın; 4) kaldırılan flag için taklitleri kaldırarak testleri güncelleyin. Bu sürecin CI aracılığıyla otomatikleştirilmesi önerilir: N günden uzun süredir değişmeyen flag'ler eski olarak işaretlenir ve kaldırma onayı gerektirir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun