DevOps & CI/CD Nathan Geeksman

Feature flags: entregue código com confiança antes de ligar a feature

Feature flags: entregue código com confiança antes de ligar a feature

Feature flags: entregue código com confiança antes de ligar a feature

Introdução

O desenvolvimento de software é um processo contínuo e desafiador, onde a entrega de funcionais em tempo hábil é uma das principais metas dos times de engenharia. No entanto, muitas vezes essa entrega é dificultada por problemas de estabilidade, segurança ou compatibilidade que surgem durante o processo de integração com as outras partes do sistema.

Nesse contexto, a utilização de flags de recursos (feature flags) se tornou uma prática cada vez mais comum. Essa abordagem permite que os desenvolvedores entreguem código com confiança antes mesmo de ligar ou utilizar determinado recurso, reduzindo assim o risco associado à entrega e melhando a experiência do usuário.

Neste artigo você aprenderá como implementar flags de recursos em seu projeto para entregar código seguro e escalável.

O que é e por que importa

Feature flags, também conhecidos como flags de recursos ou switches de recursos, são um mecanismo de programação que permite controlar a ativação ou desativação de determinados recursos ou funcionalidades em tempo de execução. Isso significa que os desenvolvedores podem criar código que esteja "pronto" para ser ativado, mas ainda não está funcionando, o que facilita a entrega de novas funcionalidades sem comprometer a estabilidade do sistema.

A motivação por trás da implementação de feature flags é reduzir o risco associado à entrega de novos recursos, permitindo que os desenvolvedores entreguem código com confiança antes mesmo de ligá-lo. Isso é especialmente útil em projetos grandes ou complexos, onde a integração de novas funcionalidades pode ser um processo demorado e arriscado.

Os feature flags permitem que os desenvolvedores:

  • Isolar recursos novos do restante do sistema;
  • Controlar o acesso a determinadas funcionalidades;
  • Monitorar o desempenho e a estabilidade de novas funcionalidades;
  • Retroceder facilmente em caso de problemas ou falhas.

A implementação de feature flags também ajuda a melhorar a experiência do usuário, pois permite que os desenvolvedores liberem recursos novos de forma controlada e escalável. Além disso, os feature flags podem ser utilizados para realizar testes A/B e validações de negócios sem comprometer a estabilidade do sistema.

Como funciona na prática

O funcionamento interno de feature flags envolve várias etapas e conceitos importantes para garantir a eficácia desse mecanismo de programação. Aqui está uma visão geral das principais características:

  • Definição de flags: Os desenvolvedores criam e definem os flags de recursos no código, especificando quais recursos ou funcionalidades estarão associados a cada flag.
  • Armazenamento dos flags: As informações sobre as feature flags são armazenadas em uma base de dados, como um sistema de gerenciamento de configurações (CM) ou até mesmo em um banco de dados da aplicação.
  • Carregamento das flags: Durante a inicialização da aplicação ou antes do uso dos recursos, os flags são carregados e registrados no sistema, permitindo que as funcionalidades associadas aos mesmos sejam controladas.
  • Acesso às funcionalidades: Com as feature flags ativadas, as funcionalidades associadas podem ser acessadas pelo usuário ou pela aplicação, dependendo do tipo de flag (por exemplo, um flag para clientes específicos).
  • Monitoramento e análise: Os sistemas que gerenciam os flags permitem a visualização das estatísticas e resultados dos recursos ativados, permitindo aos desenvolvedores tomar decisões informadas sobre o desempenho dos mesmos.
  • Retrocessão fácil: Em caso de problemas ou falhas, as feature flags podem ser rapidamente desativadas para evitar danos adicionais, facilitando a identificação e resolução dos erros.

Exemplo real

Aqui está um exemplo simples de como implementar feature flags utilizando Java e Spring Boot, considerando que estamos desenvolvendo uma aplicação que oferece desconto para novos usuários.

Definição das Feature Flags

As feature flags são definidas no código antes da inicialização do sistema. Elas podem ser armazenadas em um arquivo de configuração ou até mesmo no banco de dados, dependendo da complexidade da aplicação e da estratégia adotada.

// Definição das Feature Flags (por exemplo, em uma classe de Configurações)
@ConfigurationProperties(prefix = "app.feature-flags")
public class FeatureFlagsConfig {
  
  private boolean descontoParaNovosUsuarios;
  
  // Getters and setters...
}

// Exemplo de configuração do application.properties
app.feature-flags.desconto-para-novos-usuarios=true

Armazenamento das Feature Flags

As feature flags são armazenadas no banco de dados, permitindo que as configurações sejam dinâmicas e fáceis de manter. Nesse exemplo, consideramos um sistema de gerenciamento de configurações (CM) para armazenar essas informações.

// Exemplo de como criar uma entidade FeatureFlag no banco de dados
@Entity
public class FeatureFlag {
  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  
  private String name; // Nome da feature flag (por exemplo, "desconto_para_novos_usuarios")
  
  private Boolean value; // Valor da feature flag
  
  // Getters and setters...
}

Carregamento das Feature Flags

As feature flags são carregadas durante a inicialização do sistema, garantindo que os recursos associados às mesmas sejam controlados corretamente.

// Exemplo de como carregar as feature flags no início da aplicação
@Service
public class FeatureFlagsService {
  
  @Autowired
  private ConfigurableApplicationContext context;
  
  public void loadFeatureFlags() {
    // Carregamento das feature flags do banco de dados ou arquivo de configuração...
    
    // Ativação das feature flags para os recursos associados...
    context.getAutowireCapableBeanFactory().applyBeanDefinition("feature-flag-desconto-para-novos-usuarios", new ScopeBeanDefinitionHolder("descontoParaNovosUsuarios"));
  }
}

Acesso às funcionalidades

Com as feature flags ativadas, os recursos associados podem ser acessados pelo usuário ou pela aplicação.

// Exemplo de como utilizar uma feature flag para controlar acesso a um recurso
@Service
public class DescontoService {
  
  @Autowired
  private FeatureFlagsService featureFlagsService;
  
  public void calcularDesconto(Usuario usuario) {
    if (featureFlagsService.isDescontoParaNovosUsuariosAtivado()) {
      // Calcular e devolver o desconto...
    }
  }
}

Monitoramento e análise

Os sistemas que gerenciam as feature flags permitem a visualização das estatísticas e resultados dos recursos ativados, permitindo aos desenvolvedores tomar decisões informadas sobre o desempenho dos mesmos.

// Exemplo de como exibir estatísticas de uso de uma feature flag
@RestController
@RequestMapping("/api/feature-flags")
public class FeatureFlagsController {
  
  @Autowired
  private FeatureFlagRepository featureFlagRepository;
  
  @GetMapping("/{name}/usage-statistics")
  public ResponseEntity<UsageStatistics> getFeatureFlagUsageStatistics(@PathVariable String name) {
    // Retornar as estatísticas de uso da feature flag...
  }
}

Retrocessão fácil

Em caso de problemas ou falhas, as feature flags podem ser rapidamente desativadas para evitar danos adicionais.

// Exemplo de como desativar uma feature flag em caso de problema
@Service
public class FeatureFlagsService {
  
  public void desativarFeatureFlag(String name) {
    // Desativação da feature flag no banco de dados ou arquivo de configuração...
    
    // Alteração na lógica da aplicação para evitar uso do recurso associado à feature flag desativada...
  }
}

Essa é uma visão geral das principais características e conceitos envolvidos na implementação de feature flags. Elas podem ser adaptadas às necessidades específicas da aplicação, garantindo que os recursos sejam entregues com confiança e eficiência.

Boas práticas

1. Defina metas claras: Antes de implementar feature flags, defina objetivos e métricas para medir o sucesso das mesmas.

2. Use nomenclatura consistente: Utilize uma nomenclatura consistente para as feature flags em toda a aplicação, facilitando sua gestão e manutenção.

3. Documente cada flag: Mantenha um registro detalhado de cada feature flag, incluindo suas funcionalidades, objetivos e estatísticas de uso.

Armadilhas comuns

1. Over-engineering: Evite sobredesenvolver a lógica das feature flags, mantendo-a simples e direta.

2. Falta de isolamento: Certifique-se de que as feature flags não interagem entre si de maneira indesejada ou inconsistente.

3. Dependência excessiva: Não crie dependências exageradas em relação às feature flags, mantendo a flexibilidade da aplicação.

4. Negligência das estatísticas: Não subestime a importância de coletar e analisar as estatísticas dos recursos ativados.

Conclusão

Ao implementar feature flags de forma eficaz, sua aplicação pode beneficiar-se de entrega de código com confiança e menor risco associado ao lançamento de novas funcionalidades. É crucial evitar armadilhas como over-engineering, falta de isolamento e dependência excessiva, além disso é fundamental coletar e analisar estatísticas para otimizar as decisões relacionadas às feature flags.

Para levar sua implementação adiante, considere explorar tópicos relacionados, como:

  • Mensurando o impacto de lançamentos: Aprenda a avaliar os resultados de cada lançamento e ajuste suas estratégias em decorrência disso.
  • Integração com CI/CD: Explore formas de automatizar a gestão das feature flags ao longo do ciclo de desenvolvimento, garantindo que as mesmas estejam sempre atualizadas e ativas.
  • Monitoramento e logs: Aprenda a monitorar a aplicação em tempo real, identificando pontos críticos associados às feature flags para melhorias contínuas.

Referências

  • Martin Fowler. Feature Toggles. Disponível em: https://martinfowler.com/bliki/FeatureToggle.html. Acesso: 2024.
  • ThoughtWorks. Feature Flags in Software Development. Disponível em: https://www.thoughtworks.com/insights/blog/feature-flags-software-development. Acesso: 2024.
  • Netflix. Chaos Monkey. Disponível em: https://netflix.github.io/chaosmonkey/. Acesso: 2024.
  • Google Cloud. Feature Flags para melhorar a experiência do usuário. Disponível em: https://cloud.google.com/docs/feature-flags. Acesso: 2024.
  • Microsoft Docs. Feature flags (versão prévia). Disponível em: https://docs.microsoft.com/en-us/dotnet/architecture/microservices-implementation-patterns/common-helpers/feature-flags. Acesso: 2024.