E aí, pessoal! Já se pegaram suando frio antes de um deploy, pensando: "Será que essa nova funcionalidade vai quebrar tudo?" Ou talvez, "Como vamos testar isso em produção sem impactar os usuários?" Se sim, preparem-se para conhecer seu novo super-poder: os Feature Toggles (também conhecidos como Feature Flags)!
Inspirada no clássico artigo de Pete Hodgson no site do Martin Fowler [1], resolvi falar um pouco sobre essa técnica poderosa que permite alterar o comportamento do sistema sem mudar uma linha de código! Vamos ver como aplicar isso com Python e FastAPI, de um jeito prático.
O Que São Feature Toggles? Mais que um Simples Liga/Desliga!
Imagine que você está construindo um foguete espacial (seu software, claro!). Você tem várias seções novas: um motor de dobra espacial, um sistema de entretenimento holográfico, e um robô assistente. Você não quer lançar o foguete com tudo isso de uma vez sem testar, certo? E se o motor de dobra espacial der problema, você quer poder desligá-lo rapidamente sem ter que pousar o foguete e trocar a peça.
Feature Toggles são exatamente isso: chaves de controle no seu código que permitem ligar ou desligar funcionalidades específicas em tempo de execução. Elas desacoplam o deploy de código do lançamento de funcionalidades. Isso significa que você pode enviar código novo para produção (com a funcionalidade desligada) e ativá-la apenas quando estiver pronto, para quem quiser, ou sob certas condições.
As Categorias de Toggles
Pete Hodgson categoriza os Feature Toggles com base em sua longevidade e dinamismo. Entender essas categorias é crucial para usar os toggles de forma eficaz e evitar a temida "dívida técnica" de toggles antigos.
| Categoria | Longevidade | Dinamismo | Propósito Principal | Exemplo de Uso | Gerenciamento |
|---|---|---|---|---|---|
| Release Toggles | Curta (dias/semanas) | Baixo | Habilitar/desabilitar funcionalidades incompletas ou para lançamento coordenado. | Lançar uma nova interface de usuário para todos os clientes em uma data específica. | Remover após o lançamento completo. |
| Experiment Toggles | Média (semanas) | Alto | Testes A/B, multivariados. | Mostrar duas versões de um botão de compra para diferentes grupos de usuários para ver qual converte mais. | Remover após o experimento e decisão. |
| Ops Toggles | Curta/Longa | Alto | Controle operacional, "kill switches". | Desabilitar uma funcionalidade de alto consumo de recursos em caso de pico de tráfego. | Manter alguns "kill switches" essenciais, remover outros após estabilidade. |
| Permissioning Toggles | Longa (meses/anos) | Alto | Personalização de experiência para usuários/grupos específicos. | Funcionalidades "premium" para assinantes, acesso antecipado para beta testers. | Podem ser permanentes, parte da lógica de negócio. |
Mão na Massa: Implementando um Release Toggle com FastAPI
Vamos criar um cenário simples: uma API FastAPI que tem uma nova funcionalidade de "cálculo de frete otimizado". Queremos fazer o deploy do código, mas só ativar essa funcionalidade para um grupo seleto de usuários ou em um momento específico.
1. Setup Básico do Projeto
Primeiro, crie um projeto FastAPI (usando Poetry, claro!):
poetry new feature-toggle-app
cd feature-toggle-app
poetry add fastapi uvicorn
Crie um arquivo main.py:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def hello_world():
return {"status": "ok"}
2. O Nosso "Gerenciador" de Toggles
Para simplificar, vamos usar um dicionário simples para gerenciar nossos toggles. Em um cenário real, isso viria de um serviço externo (como LaunchDarkly, Unleash, ou um banco de dados/config server).
Crie um arquivo feature_flags.py:
# feature_flags.py
FEATURE_TOGGLES = {
"OTIMIZED_SHIPPING": False, # Nosso Release Toggle
"NEW_DASHBOARD_BETA": False, # Exemplo de Permissioning/Experiment Toggle
}
def is_feature_enabled(feature_name: str) -> bool:
return FEATURE_TOGGLES.get(feature_name, False)
3. Integrando o Toggle no FastAPI
Agora, vamos usar nosso toggle na API. Adicionaremos um endpoint para o cálculo de frete. Se o toggle OTIMIZED_SHIPPING estiver False, ele usará o cálculo antigo. Se estiver True, usará o novo.
Atualize main.py:
# main.py
from fastapi import FastAPI, HTTPException
from feature_flags import is_feature_enabled
app = FastAPI()
@app.get("/")
async def hello_world():
return {"status": "ok"}
@app.get("/shipping_cost/{item_id}")
async def get_shipping_cost(item_id: int):
if is_feature_enabled("OTIMIZED_SHIPPING"):
# Lógica do novo cálculo de frete otimizado
cost = item_id * 0.5 # Exemplo: cálculo mais barato
return {"item_id": item_id, "cost": cost, "method": "optimized"}
else:
# Lógica do cálculo de frete antigo
cost = item_id * 1.0 # Exemplo: cálculo padrão
return {"item_id": item_id, "cost": cost, "method": "standard"}
# Exemplo de um endpoint que só aparece se o toggle estiver ativo
@app.get("/admin/new_dashboard")
async def new_admin_dashboard():
if not is_feature_enabled("NEW_DASHBOARD_BETA"):
raise HTTPException(status_code=404, detail="New dashboard not available")
return {"message": "Bem-vindo ao novo painel de administração beta!"}
Para rodar a aplicação:
poetry run uvicorn main:app --reload
Agora, você pode testar:
- Acesse
http://127.0.0.1:8000/shipping_cost/10. Você verá o método "standard". - Altere
OTIMIZED_SHIPPINGparaTrueemfeature_flags.pye salve. Ouvicornrecarregará. - Acesse novamente
http://127.0.0.1:8000/shipping_cost/10. Agora você verá o método "optimized"!
Isso é um Release Toggle em ação! Você pode fazer o deploy do código com a funcionalidade "desligada" e ativá-la quando quiser, sem um novo deploy.
Boas Práticas: Evitando a "Dívida Técnica" dos Toggles
Feature Toggles são poderosos, mas com grandes poderes vêm grandes responsabilidades. Sem cuidado, seu código pode virar uma teia de if/elses. Aqui vão algumas dicas:
- Nomeie Bem Seus Toggles: Nomes claros como
OTIMIZED_SHIPPINGsão melhores queFEATURE_A. O nome deve indicar o propósito da funcionalidade. - Mantenha a Taxonomia: Use as categorias (Release, Experiment, Ops, Permissioning) para guiar a longevidade e o gerenciamento.
- Remova Toggles Obsoletos: Toggles de Release e Experiment devem ser removidos assim que cumprirem seu propósito. Eles são dívida técnica! Agende a remoção.
- Isolamento de Código: Tente isolar o código da funcionalidade por trás do toggle. Evite espalhar
if is_feature_enabled(...)por todo o codebase. - Testes: Teste ambos os caminhos (toggle ligado e desligado). Seus testes devem cobrir todas as variações.
- Ferramentas de Gerenciamento: Para projetos maiores, considere usar ferramentas dedicadas como LaunchDarkly, Unleash, ou Split.io. Elas oferecem dashboards, segmentação de usuários, e gerenciamento centralizado.
Gerenciamento: Quando e Como Dizer Adeus aos Toggles
O maior desafio dos Feature Toggles é o gerenciamento. Um toggle de Release que fica muito tempo no código se torna um toggle de Permissioning ou Ops por acidente, adicionando complexidade desnecessária.
- Release Toggles: Remova-os assim que a funcionalidade for totalmente lançada e estabilizada. Faça um refactor para remover o
ife o código antigo. - Experiment Toggles: Remova-os após a conclusão do experimento e a decisão de manter ou descartar a funcionalidade.
- Ops Toggles: Mantenha apenas os "kill switches" essenciais. Revise-os periodicamente.
- Permissioning Toggles: Podem ser de longa duração, mas devem ser bem documentados e tratados como parte da lógica de negócio.
Conclusão: O Futuro da Entrega de Software é Flexível!
Feature Toggles são uma ferramenta essencial para equipes que buscam Continuous Delivery e Agilidade. Eles permitem que você:
- Reduza o risco de deploys.
- Faça testes A/B e experimentos em produção.
- Libere funcionalidades para subconjuntos de usuários.
- Reaja rapidamente a problemas em produção.
Ao adotar essa técnica com sabedoria, você não apenas melhora a qualidade do seu software, mas também a confiança e a velocidade da equipe.
Referências
[1] Fowler, Martin. "Feature Toggles (aka Feature Flags)". MartinFowler.com, 2017. Disponível em: https://martinfowler.com/articles/feature-toggles.html
Top comments (0)