Como usar feature flags em APIs para rollout gradual de mudanças
1. Conceitos Fundamentais de Feature Flags em APIs
Feature flags (ou toggles) são mecanismos de configuração que permitem ativar ou desativar funcionalidades em tempo de execução, sem necessidade de deploy. No contexto de APIs REST, elas funcionam como interruptores controlados externamente que determinam qual versão de um recurso será executada.
Existem dois tipos principais de flags:
- Release toggles: controlam a liberação de novas funcionalidades para produção, permitindo ativação gradual.
- Experimentação toggles: usadas para testes A/B, onde diferentes grupos de usuários veem comportamentos distintos.
O ciclo de vida de uma feature flag segue quatro estágios:
1. Criação: define-se a flag, seu comportamento padrão e os alvos iniciais
2. Ativação gradual: libera-se para um percentual pequeno de tráfego
3. Estabilização: monitora-se métricas e expande-se a liberação
4. Remoção: quando a funcionalidade está estável, remove-se o código legado e a flag
2. Arquitetura de Integração de Feature Flags em APIs
A avaliação de flags pode seguir duas abordagens arquiteturais:
Abordagem centralizada: um serviço dedicado gerencia todas as flags. As APIs consultam esse serviço via SDK ou chamada HTTP. Vantagem: gerenciamento unificado. Desvantagem: latência adicional.
Abordagem descentralizada: cada serviço possui seu próprio mecanismo de flags, geralmente baseado em arquivos de configuração ou variáveis de ambiente. Vantagem: simplicidade e baixa latência. Desvantagem: difícil gerenciamento em escala.
Para minimizar impacto na latência, implementa-se cache local com TTL configurável:
// Exemplo de configuração de cache para feature flags
feature_flags:
cache:
strategy: local_in_memory
ttl_seconds: 30
max_size: 1000
fallback:
default_value: false
log_on_fallback: true
Integrações comuns incluem provedores como LaunchDarkly, Unleash e Split, que oferecem SDKs otimizados. Para implementação própria, utiliza-se um banco de dados chave-valor com cache Redis.
3. Estratégias de Rollout Gradual com Feature Flags
Lançamento por percentual de usuários: utiliza-se hash consistente do identificador do usuário para determinar se a flag deve ser ativada. Exemplo:
// Função de hash para distribuição uniforme
function shouldActivateFlag(userId: string, percentage: number): boolean {
const hash = hashCode(userId) % 100;
return hash < percentage;
}
Lançamento por segmentos: flags podem ser ativadas com base em atributos como:
- Localização geográfica (país, região)
- Plano de assinatura (free, premium, enterprise)
- Versão do cliente (app mobile 2.3+, web)
Canary releases com flags: combina-se o deploy de uma nova versão do serviço com uma flag que controla o tráfego para essa versão. Exemplo de configuração:
# Configuração de canary release
canary:
new_version: v2.1.0
traffic_percentage: 5
flag_name: api.search.new-algorithm.enabled
metrics_monitor:
error_rate_threshold: 0.01
latency_p99_threshold_ms: 500
4. Implementação Técnica: Exemplos Práticos em APIs REST
Middleware de feature flags para validação em endpoints:
// Middleware para avaliação de feature flag
import { FeatureFlagService } from './services/feature-flags';
export function featureFlagMiddleware(flagName: string) {
return async (req, res, next) => {
try {
const userId = req.headers['x-user-id'];
const isEnabled = await FeatureFlagService.evaluate(flagName, {
userId,
region: req.headers['x-region'],
plan: req.headers['x-plan']
});
if (!isEnabled) {
return res.status(404).json({
error: 'Resource not available',
code: 'FEATURE_NOT_AVAILABLE'
});
}
next();
} catch (error) {
// Fallback seguro: se o serviço de flags falhar, permite acesso
console.error('Feature flag evaluation failed:', error);
next();
}
};
}
Controle de versionamento interno sem alterar contrato público:
// Endpoint de busca com flag para novo algoritmo
app.get('/api/search', async (req, res) => {
const query = req.query.q;
const userId = req.headers['x-user-id'];
const useNewAlgorithm = await flags.evaluate(
'search.new-algorithm.enabled',
{ userId }
);
if (useNewAlgorithm) {
const results = await searchService.newAlgorithm(query);
log.info('New search algorithm used', { userId, query });
return res.json(results);
}
const results = await searchService.legacyAlgorithm(query);
return res.json(results);
});
Avaliação com fallback seguro e logs estruturados:
// Serviço de feature flags com fallback e logging
class FeatureFlagService {
async evaluate(flagName: string, context: any): Promise<boolean> {
try {
const result = await this.provider.evaluate(flagName, context);
log.info('Feature flag evaluated', {
flag: flagName,
userId: context.userId,
result,
timestamp: new Date().toISOString()
});
return result;
} catch (error) {
log.error('Feature flag evaluation failed', {
flag: flagName,
error: error.message
});
// Fallback: retorna false (funcionalidade desativada)
return false;
}
}
}
5. Boas Práticas de Nomenclatura e Organização de Flags
Adote um padrão de nomenclatura consistente: {serviço}.{recurso}.{comportamento}
# Exemplos de nomenclatura padronizada
payment.new-gateway.enabled
payment.new-gateway.timeout_ms
search.vector-index.active
auth.biometric-login.rollout_percentage
notifications.push-v2.target_platforms
Versionamento semântico de flags: inclua informações de deprecação no nome:
# Nomenclatura com data de deprecação
payment.legacy-gateway.deprecated_2024-12-31
search.old-algorithm.removal_scheduled_2025-03-01
Documentação automatizada: gere um manifesto de flags ativas:
# Manifesto de feature flags (gerado automaticamente)
flags:
- name: search.new-algorithm.enabled
status: active
rollout_percentage: 25
created: 2024-01-15
deprecated: null
impact: Alters search result ordering
- name: payment.legacy-gateway.enabled
status: deprecated
rollout_percentage: 100
created: 2023-06-01
deprecated: 2024-12-31
impact: Affects payment processing flow
6. Monitoramento, Observabilidade e Remoção de Flags
Métricas essenciais para cada flag:
# Métricas de observabilidade para feature flags
metrics:
- name: feature_flag.error_rate
type: counter
labels: [flag_name, group]
- name: feature_flag.latency_ms
type: histogram
labels: [flag_name, group]
- name: feature_flag.evaluation_count
type: counter
labels: [flag_name, result]
Alertas para comportamento inesperado:
# Regras de alerta para feature flags
alerts:
- name: high_error_rate_on_new_feature
condition: error_rate > 0.05
for: 5m
severity: critical
action: rollback_flag
- name: latency_degradation
condition: latency_p99 > 2x baseline
for: 10m
severity: warning
action: notify_team
Processo de limpeza de flags obsoletas:
# Script de identificação de flags obsoletas
SELECT flag_name, last_evaluation, rollout_percentage
FROM feature_flags
WHERE last_evaluation < NOW() - INTERVAL '90 days'
OR rollout_percentage = 100
AND created < NOW() - INTERVAL '180 days';
7. Casos de Uso Avançados e Armadilhas Comuns
A/B testing em endpoints de busca: utilize flags para expor diferentes algoritmos:
# Configuração de A/B test para busca
ab_test:
flag: search.ranking-algorithm.experiment
variants:
- name: control
percentage: 50
algorithm: tf-idf
- name: treatment
percentage: 50
algorithm: neural-ranking
metrics:
- click_through_rate
- session_duration
Gerenciamento de dependências entre flags (flag entanglement):
# Matriz de dependências entre flags
dependencies:
- flag: payment.new-gateway.enabled
depends_on:
- flag: infrastructure.new-payment-service.active
required: true
- flag: compliance.audit-v2.enabled
required: false
- flag: search.vector-index.active
depends_on:
- flag: infrastructure.vector-db.deployed
required: true
Problemas comuns e como evitá-los:
- Poluição de código: estabeleça um limite máximo de flags ativas por serviço (ex: 10 flags simultâneas)
- Testes insuficientes: implemente testes unitários que cubram ambos os estados de cada flag
- Riscos de segurança: nunca use flags para controlar autenticação ou autorização; sempre valide permissões no backend
Referências
- LaunchDarkly Documentation: Feature Flags in REST APIs — Guia oficial sobre implementação de feature flags em APIs REST com boas práticas de rollout gradual
- Unleash Documentation: Feature Toggle Architecture — Documentação técnica sobre arquitetura de feature toggles, incluindo estratégias de cache e avaliação
- Martin Fowler: Feature Toggles (aka Feature Flags) — Artigo seminal sobre o padrão de feature toggles, com categorização e ciclo de vida
- Split.io Blog: Gradual Rollout Strategies for APIs — Artigo técnico sobre estratégias de rollout gradual com exemplos práticos para APIs
- AWS Architecture Blog: Implementing Feature Flags for Microservices — Guia da AWS sobre implementação de feature flags em arquiteturas de microsserviços
- FeatureFlags.dev: Feature Flag Naming Conventions — Recurso sobre boas práticas de nomenclatura e organização de feature flags
- Honeycomb Blog: Observability for Feature Flags — Artigo sobre monitoramento e observabilidade de feature flags em produção