Introduction of library ff4j that realizes FeatureToggle with Spring Boot

What is Feature Toggle?

For example, as shown below, prepare a boolean variable called ʻuseNewAlgorithm to use a new algorithm, and use it in situations where the new algorithm and the old algorithm are used properly according to the true / false of ʻuseNewAlgorithm.

  function reticulateSplines(){
    var useNewAlgorithm = false;
    // useNewAlgorithm = true; // UNCOMMENT IF YOU ARE WORKING ON THE NEW SR ALGORITHM
  
    if( useNewAlgorithm ){
      return enhancedSplineReticulation();
    }else{
      return oldFashionedSplineReticulation();
    }
  }
  
  function oldFashionedSplineReticulation(){
    // current implementation lives here
  }
  
  function enhancedSplineReticulation(){
    // TODO: implement better SR algorithm
  }

FeatureFlag is often used when providing new features with a fixed release timing, canary releases, A / B testing, etc.

FF4J

https://ff4j.github.io/ スクリーンショット 2020-01-07 22.29.42.png

FF4j is a Java library that can easily implement FeatureToggle.

--Real-time Toggle switching using Web Console and REST API --Persistence of state using various storages --Feature usage monitoring

Various functions such as are provided.

Installation procedure

Creating a project

Create a project by selecting only Spring Reactive Web, lombok from Spring Initializr that everyone loves.

Introduction of FF4j

Add a dependency to pom.xml.

pom.xml


<dependency>
    <groupId>org.ff4j</groupId>
    <artifactId>ff4j-spring-boot-starter</artifactId>
    <version>1.8</version>
</dependency>

Create Bean definition & Feature for FF4j.

FF4JConfiguration.java


import org.ff4j.FF4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FF4JConfiguration {
    @Bean
    public FF4j ff4j() {
        FF4j ff4j = new FF4j()
                .createFeature(awesomeFeature())
                .createFeature(greatFeature())
                .createFeature(excellentFeature());
        return ff4j;
    }

    private Feature awesomeFeature() {
        return new Feature("AwesomeFeature", true);
    }

    private Feature greatFeature() {
        return new Feature("GreatFeature", false);
    }

    private Feature excellentFeature() {
        return new Feature("ExcellentFeature", false);
    }
}

This time, we have defined three features, ʻAwesomeFeature, GreatFeature, and ʻExcellentFeature, and turned on only ʻAwesomeFeature`.

Implement Controller using FF4j. In the Controller that returns only a simple message, if the three defined features are turned on, it is added to the message according to the features.

GreetingController.java


@RestController
@RequiredArgsConstructor
public class GreetingController {

    //Constructor injection
    private final FF4j ff4j;

    @GetMapping
    public String greeting() {
        List<String> features = new ArrayList<>();
        addFeatures(features);
        String greeting = String.format("Hello, %s World!!", String.join(" ", features));

        return greeting;
    }

    //Processing of each feature
    private void addFeatures(List<String> features) {
        if(ff4j.check("AwesomeFeature")) {
            features.add("Awesome");
        }

        if(ff4j.check("GreatFeature")) {
            features.add("Great");
        }

        if(ff4j.check("ExcellentFeature")) {
            features.add("Excellent");
        }
    }
}

Launch the application and go to http: // localhost: 8080. スクリーンショット 2019-11-28 0.13.29.png

By default, ʻAwesome Feature is enabled, so the message will be displayed as Hello, Awesome World! `.

Introducing Web Console

Next, install the FF4j management console. In the previous state, it was necessary to switch Feature on / off on the source code, but by using WebConsole, it is possible to switch Feature on / off while the application is running.

Add a dependency to pom.xml.

<dependency>
	<groupId>org.ff4j</groupId>
	<artifactId>ff4j-web</artifactId>
	<version>1.8</version>
</dependency>
<dependency>
	<groupId>org.thymeleaf</groupId>
	<artifactId>thymeleaf</artifactId>
	<version>2.1.4.RELEASE</version>
</dependency>

Add a new bean definition.

@Configuration
@ConditionalOnClass({ConsoleServlet.class, FF4jDispatcherServlet.class})
@AutoConfigureAfter(FF4JConfiguration.class)
public class FF4JWebConfiguration extends SpringBootServletInitializer {

    @Bean
    public ServletRegistrationBean<FF4jDispatcherServlet> ff4jDispatcherServletRegistrationBean(FF4jDispatcherServlet ff4jDispatcherServlet)
    {
        ServletRegistrationBean<FF4jDispatcherServlet> bean = new ServletRegistrationBean<>(ff4jDispatcherServlet, "/ff4j-web-console/*");
        bean.setName("ff4j-console");
        bean.setLoadOnStartup(1);
        return bean;
    }

    @Bean
    @ConditionalOnMissingBean
    public FF4jDispatcherServlet getFF4jDispatcherServlet(FF4j ff4j) {
        FF4jDispatcherServlet ff4jDispatcherServlet = new FF4jDispatcherServlet();
        ff4jDispatcherServlet.setFf4j(ff4j);
        return ff4jDispatcherServlet;
    }

}

Start and access http: // localhost: 8080 / ff4j-web-console. スクリーンショット 2019-11-28 0.15.49.png

You can see the currently defined Features in the Features menu, Feature turns on / off as the toggle is turned on / off.

スクリーンショット 2019-11-28 0.17.32.png

GIF animation demo

I will also post a demo of the contents explained above taken with GIF animation. For your reference. ff4j-demo.gif

Summary

I gave a brief introduction of FF4j. Feature Toggle is a powerful technique, but if you don't set an operation policy, a chaotic code base will be created, so I want to be careful when operating it. It is necessary to have a framework such as separating the features to be DI for each profile and defining coding standards and review points.

reference

martinFowler.com - FeatureToggle: https://martinfowler.com/articles/feature-toggles.html FF4j: https://ff4j.github.io/ Repository used this time: https://github.com/IshinFUKUOKA/ff4j-demo

Recommended Posts

Introduction of library ff4j that realizes FeatureToggle with Spring Boot
[Introduction to Spring Boot] Authentication function with Spring Security
Download with Spring Boot
Access the built-in h2db of spring boot with jdbcTemplate
Create Restapi with Spring Boot ((1) Until Run of App)
How to boot by environment with Spring Boot of Maven
Generate barcode with Spring Boot
Hello World with Spring Boot
Get started with Spring boot
Hello World with Spring Boot!
Accelerate testing of Validators that require DI in Spring Boot
A story packed with the basics of Spring Boot (solved)
Extract SQL to property file with jdbcTemplate of spring boot
Run LIFF with Spring Boot
SNS login with Spring Boot
Introduction to Spring Boot ① ~ DI ~
Introduction to Spring Boot ② ~ AOP ~
Spring Boot starting with Docker
Hello World with Spring Boot
Set cookies with Spring Boot
Use Spring JDBC with Spring Boot
Add module with Spring Boot
Getting Started with Spring Boot
Spring Boot application that specifies DB connection settings with parameters
Introduction to Spring Boot Part 1
Easy library introduction with Maven!
Create microservices with Spring Boot
Send email with spring boot
Introduction to Spring Boot x OpenAPI ~ OpenAPI made with Generation gap pattern ~
A story that struggled with the introduction of Web Apple Pay
See the behavior of entity update with Spring Boot + Spring Data JPA
[Beginner] Let's write REST API of Todo application with Spring Boot
Use Basic Authentication with Spring Boot
gRPC on Spring Boot with grpc-spring-boot-starter
Hot deploy with Spring Boot development
Spring Boot programming with VS Code
Until "Hello World" with Spring Boot
Inquiry application creation with Spring Boot
Going out of message (Spring boot)
Get validation results with Spring Boot
(Intellij) Hello World with Spring Boot
Google Cloud Platform with Spring Boot 2.0.0
Check date correlation with Spring Boot
I tried GraphQL with Spring Boot
[Java] LINE integration with Spring Boot
A memo that touched Spring Boot
Beginning with Spring Boot 0. Use Spring CLI
I tried Flyway with Spring Boot
Message cooperation started with Spring Boot
Spring Boot gradle build with Docker
How to read Body of Request multiple times with Spring Boot + Spring Security
Introduction to Java development environment & Spring Boot application created with VS Code
Processing at application startup with Spring Boot
Hello World with Eclipse + Spring Boot + Maven
Send regular notifications with LineNotify + Spring Boot
Perform transaction confirmation test with Spring Boot
HTTPS with Spring Boot and Let's Encrypt
Try using Spring Boot with VS Code
Start web application development with Spring Boot
WebMvcConfigurer Memorandum of Understanding for Spring Boot 2.0 (Spring 5)
I tried Lazy Initialization with Spring Boot 2.2.0