Feature flags en Java : comment activer des fonctionnalités sans redémarrer l'application

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Feature flags en Java : comment activer des fonctionnalités sans redémarrer l'application

\n\n

Imaginez : vous avez passé une semaine à développer une nouvelle fonctionnalité — un formulaire de contact avec une suggestion automatique magique. Vous l'avez fusionnée et déployée en production. Et là — un bug. Les utilisateurs ne peuvent pas envoyer de message. Vous devez annuler d'urgence le commit, reconstruire le JAR, redémarrer le serveur. Tout le monde déteste ce moment.

\n\n

Et si vous pouviez simplement appuyer sur un bouton "désactiver" directement dans l'interface d'administration, sans toucher au code ? Ou activer la fonctionnalité uniquement pour 10 % des utilisateurs afin de tester la charge ? Ou lancer un test A/B où la moitié voit le nouveau design et l'autre moitié l'ancien ?

\n\n

Tout cela, c'est la magie des feature flags (aussi appelés feature toggles). Dans cet article, nous allons voir comment les implémenter en Java — du simple Enum aux solutions industrielles comme Togglz et LaunchDarkly. C'est parti !

\n\n

Qu'est-ce qu'un feature flag et pourquoi en avez-vous besoin ?

\n\n

Un feature flag (ou feature toggle) est un interrupteur conditionnel dans le code qui permet d'activer ou de désactiver une fonctionnalité sans modifier le code source ni redéployer l'application.

\n\n

Cela ressemble à un simple if ? Mais la force réside dans la gestion. Vous stockez l'état des flags dans un fichier de configuration, une base de données ou un service externe. Vous changez la valeur — la fonctionnalité s'active ou se désactive instantanément.

\n\n

Pourquoi en avez-vous besoin dans les projets Java ?

\n\n
    \n
  • Trunk-based development — fusionnez des fonctionnalités inachevées dans la branche main en les cachant derrière un flag. Les collègues ne verront pas les bugs, et vous pouvez terminer tranquillement.
  • \n
  • Canary releases — activez la fonctionnalité pour 5 % des utilisateurs, surveillez les métriques, puis pour 50 %, puis pour tout le monde.
  • \n
  • Kill switch — si une fonctionnalité plante en production, vous la désactivez simplement d'un seul bouton.
  • \n
  • Tests A/B — comparez le comportement des utilisateurs avec et sans la fonctionnalité.
  • \n
  • Personnalisation — activez les fonctionnalités premium uniquement pour les clients payants.
  • \n
\n\n

Le risque principal est la dette technique. Si vous ne supprimez pas les anciens flags, le code se transforme en une toile d'araignée de if-else. Nous en parlerons également.

\n\n

La méthode la plus simple : Enum + Properties

\n\n

Commençons par une approche de base. Créons une énumération de flags et lisons-les depuis application.properties.

\n\n
public enum FeatureFlag {\n    NEW_CHECKOUT_FLOW,\n    AI_RECOMMENDATIONS,\n    DARK_MODE\n}
\n\n

Chargeons les flags dans un service :

\n\n
@Component\npublic class FeatureFlagService {\n\n    private final Map<FeatureFlag, Boolean> flags = new HashMap<>();\n\n    public FeatureFlagService(@Value("${features.new-checkout-flow:false}") boolean newCheckout,\n                              @Value("${features.ai-recommendations:false}") boolean aiRec,\n                              @Value("${features.dark-mode:false}") boolean darkMode) {\n        flags.put(FeatureFlag.NEW_CHECKOUT_FLOW, newCheckout);\n        flags.put(FeatureFlag.AI_RECOMMENDATIONS, aiRec);\n        flags.put(FeatureFlag.DARK_MODE, darkMode);\n    }\n\n    public boolean isEnabled(FeatureFlag flag) {\n        return flags.getOrDefault(flag, false);\n    }\n}
\n\n

Utilisation dans le code :

\n\n
if (featureFlagService.isEnabled(FeatureFlag.NEW_CHECKOUT_FLOW)) {\n    // nouveau flux de commande\n} else {\n    // ancien flux\n}
\n\n

Avantages : simplicité, pas de dépendances inutiles. Inconvénients : pour modifier la valeur, vous devez redémarrer l'application. Ce n'est pas tout à fait "sans redémarrage", mais pour les petits projets, c'est acceptable.

\n\n

Flags dynamiques : base de données ou Redis

\n\n

Si vous voulez modifier les flags à la volée — stockez-les dans une base de données ou Redis. Créons une table :

\n\n
CREATE TABLE feature_flags (\n    name VARCHAR(100) PRIMARY KEY,\n    enabled BOOLEAN NOT NULL DEFAULT FALSE,\n    updated_at TIMESTAMP\n);
\n\n

Service avec mise en cache (pour ne pas solliciter la base de données à chaque requête) :

\n\n
@Service\npublic class DynamicFeatureFlagService {\n\n    private final JdbcTem                

Blogs

Book Recommendations