Un guide pour flips pour le printemps

Un guide pour flips pour le printemps

1. Vue d'ensemble

Dans ce didacticiel, nous allons examinerFlips, une bibliothèque qui implémente des indicateurs de fonctionnalité sous la forme d'annotations puissantes pour les applications Spring Core, Spring MVC et Spring Boot.

Les drapeaux de fonctionnalités (ou bascules) sont un modèle pour fournir de nouvelles fonctionnalités rapidement et en toute sécurité. Ces bascules nous permettent de modifier le comportement des applicationswithout changing or deploying new code. Le blog de Martin Fowler a un article très instructif sur les indicateurs de fonctionnalitéhere.

2. Dépendance Maven

Avant de commencer, nous devons ajouter la bibliothèque Flips à nospom.xml:


    com.github.feature-flip
    flips-core
    1.0.1

Maven Central a leslatest version of the library, et le projet Github esthere.

Bien sûr, nous devons également inclure un printemps:


    org.springframework.boot
    spring-boot-starter-web
    1.5.10.RELEASE

Puisque Flips n'est pas encore compatible avec Spring version 5.x, nous allons utiliser leslatest version of Spring Boot in the 4.x branch.

3. Un service REST simple pour les flips

Créons un projet Spring Boot simple pour ajouter et basculer de nouvelles fonctionnalités et indicateurs.

Notre application REST donnera accès aux ressources deFoo:

public class Foo {
    private String name;
    private int id;
}

Nous allons simplement créer unService qui gère une liste deFoos:

@Service
public class FlipService {

    private List foos;

    public List getAllFoos() {
        return foos;
    }

    public Foo getNewFoo() {
        return new Foo("New Foo!", 99);
    }
}

Nous ferons référence à des méthodes de service supplémentaires au fur et à mesure, mais cet extrait de code devrait suffire à illustrer ce queFlipService fait dans le système.

Et bien sûr, nous devons créer un contrôleur:

@RestController
public class FlipController {

    private FlipService flipService;

    // constructors

    @GetMapping("/foos")
    public List getAllFoos() {
        return flipService.getAllFoos();
    }
}

4. Fonctions de contrôle basées sur la configuration

L'utilisation la plus élémentaire de Flips est d'activer ou de désactiver une fonctionnalité basée sur la configuration. Flips a plusieurs annotations pour cela.

4.1. Propriété de l'environnement

Imaginons que nous ayons ajouté une nouvelle capacité àFlipService; récupération deFoos par leur identifiant.

Ajoutons la nouvelle requête au contrôleur:

@GetMapping("/foos/{id}")
@FlipOnEnvironmentProperty(
  property = "feature.foo.by.id",
  expectedValue = "Y")
public Foo getFooById(@PathVariable int id) {
    return flipService.getFooById(id)
      .orElse(new Foo("Not Found", -1));
}

Le@FlipOnEnvironmentProperty contrôle si cette API est disponible ou non.

En termes simples, lorsquefeature.foo.by.id estY, nous pouvons faire des requêtes par Id. S'il n'est pas (ou pas du tout défini), Flips désactivera la méthode API.

Si une fonctionnalité n'est pas activée, Flips lanceraFeatureNotEnabledException et Spring renverra «Non implémenté» au client REST.

Lorsque nous appelons l'API avec la propriété définie surN, voici ce que nous voyons:

Status = 501
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {
    "errorMessage": "Feature not enabled, identified by method
      public com.example.flips.model.Foo
      com.example.flips.controller.FlipController.getFooById(int)",
    "className":"com.example.flips.controller.FlipController",
    "featureName":"getFooById"
}

Comme prévu, Spring attrape lesFeatureNotEnabledException et renvoie le statut 501 au client.

4.2. Profil actif

Spring nous a depuis longtemps donné la possibilité de mapper des beans vers différentsprofiles, tels quedev,test ouprod. Étendre cette fonctionnalité pour mapper les indicateurs de fonctionnalité sur le profil actif est intuitif.

Voyons comment les fonctionnalités sont activées ou désactivées en fonction desSpring Profile actifs:

@RequestMapping(value = "/foos", method = RequestMethod.GET)
@FlipOnProfiles(activeProfiles = "dev")
public List getAllFoos() {
    return flipService.getAllFoos();
}

L'annotation@FlipOnProfiles accepte une liste de noms de profil. Si le profil actif est dans la liste, l'API est accessible.

4.3. Expressions de printemps

Spring’s Expression Language (SpEL) est le puissant mécanisme de manipulation de l'environnement d'exécution. Flips nous offre également un moyen de basculer entre les fonctionnalités.

@FlipOnSpringExpression bascule une méthode basée sur une expression SpEL qui renvoie un booléen.

Utilisons une expression simple pour contrôler une nouvelle fonctionnalité:

@FlipOnSpringExpression(expression = "(2 + 2) == 4")
@GetMapping("/foo/new")
public Foo getNewFoo() {
    return flipService.getNewFoo();
}

4.4. Désactiver

Pour désactiver complètement une fonctionnalité, utilisez@FlipOff:

@GetMapping("/foo/first")
@FlipOff
public Foo getFirstFoo() {
    return flipService.getLastFoo();
}

Dans cet exemple,getFirstFoo() est complètement inaccessible.

Comme nous le verrons ci-dessous, nous pouvons combiner des annotations Flips, ce qui permet d'utiliser@FlipOff pour désactiver une fonctionnalité en fonction de l'environnement ou d'autres critères.

5. Fonctions de contrôle avec date / heure

Les flips peuvent basculer sur une fonctionnalité en fonction d'une date / heure ou du jour de la semaine. Lier la disponibilité d'une nouvelle fonctionnalité au jour ou à la date présente des avantages évidents.

5.1. Date et l'heure

@FlipOnDateTime accepte le nom d'une propriété formatée au formatISO 8601.

Définissons donc une propriété indiquant une nouvelle fonctionnalité qui sera active le 1er mars:

first.active.after=2018-03-01T00:00:00Z

Ensuite, nous allons écrire une API pour récupérer le premier Foo:

@GetMapping("/foo/first")
@FlipOnDateTime(cutoffDateTimeProperty = "first.active.after")
public Foo getFirstFoo() {
    return flipService.getLastFoo();
}

Flips vérifiera la propriété nommée. Si la propriété existe et que la date / heure spécifiée est passée, la fonctionnalité est activée.

5.2. Jour de la semaine

La bibliothèque fournit@FlipOnDaysOfWeek, ce qui est utile pour des opérations telles que les tests A / B:

@GetMapping("/foo/{id}")
@FlipOnDaysOfWeek(daysOfWeek={DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY})
public Foo getFooByNewId(@PathVariable int id) {
    return flipService.getFooById(id).orElse(new Foo("Not Found", -1));
}

getFooByNewId() n'est disponible que les lundis et mercredis.

6. Remplacer un haricot

Activer et désactiver les méthodes est utile, mais nous pouvons souhaiter introduire un nouveau comportement via de nouveaux objets. @FlipBean demande à Flips d'appeler une méthode dans un nouveau bean.

Une annotation Flips peut fonctionner sur n'importe quel Spring@Component. Jusqu'à présent, nous n'avons modifié que nos@RestController, essayons de modifier nosService.

Nous allons créer un nouveau service avec un comportement différent deFlipService:

@Service
public class NewFlipService {
    public Foo getNewFoo() {
        return new Foo("Shiny New Foo!", 100);
    }
}

Nous remplacerons lesgetNewFoo() de l'ancien service par la nouvelle version:

@FlipBean(with = NewFlipService.class)
public Foo getNewFoo() {
    return new Foo("New Foo!", 99);
}

Les flips dirigeront les appels versgetNewThing() versNewFlipService. @FlipBean est une autre bascule qui est plus utile lorsqu'elle est combinée avec d'autres. Regardons cela maintenant.

7. Combinaison de bascules

Nous combinons les bascules en spécifiant plus d'un. Flips les évalue en séquence, avec la logique implicite «ET». Par conséquent, ils doivent tous être vrais pour activer la fonctionnalité.

Combinons deux de nos exemples précédents:

@FlipBean(
  with = NewFlipService.class)
@FlipOnEnvironmentProperty(
  property = "feature.foo.by.id",
  expectedValue = "Y")
public Foo getNewFoo() {
    return new Foo("New Foo!", 99);
}

Nous avons utilisé le nouveau service configurable.

8. Conclusion

Dans ce bref guide, nous avons créé un simple service Spring Boot et activé et désactivé les API à l'aide d'annotations Flips. Nous avons vu comment les fonctionnalités sont basculées à l’aide des informations de configuration et de la date / heure, mais aussi comment les fonctions peuvent être basculées en échangeant des beans lors de l’exécution.

Des échantillons de code, comme toujours, peuvent être trouvésover on GitHub.