Feature flag (also known as feature toggle or feature switch) is a technique that allows separating feature release from deploying code during software development. That way, an application is under full control since developers can set who sees its features and when. This makes feature toggles integral to the continuous delivery approach which facilitates quick and reliable releases.
The credits for introducing the concept of feature flagging go to Martin Fowler and Facebook’s development team. Feature toggles were presented as an alternative to feature branches, i.e. maintaining multiple source-code branches. Feature branches make feature releases tied to code deployment.
When marketers are targeting users based on various attributes — age, location, gender, etc. — they want to ensure the information they want to share gets to the specific users. Thus, user targeting gives control over what is shared, with whom, and when. Something similar happens with feature flagging.
When a web application loads, it will use the specific user’s attributes to determine what features will be shown. For example, canary launches imply a specific feature functioning only for a small group of users. The group can be chosen from the internal users, or based on demographics, or deliberately at random; it varies from company to company.
That way, after logging in, all the ‘canaries’ will see the newest features firsthand. The other users won’t see anything new yet. With time, when new features prove their efficiency, they will be gradually introduced to a larger audience. If new features prove to be less than hoped for, they can be turned off.
According to Martin Fowler, feature toggles can be classified as follows:
Feature flags in Java work by the same principle — they help when it’s still too early to introduce new features in a Java application, or if they should be available, only for specific users. Reasons may vary. For example, the business or application itself, might not be ready. So it is handy to add a specific feature toggle and default it to ‘off’ until it is needed.
Also, there are feature toggle management tools that allow adding feature toggles to improve the code. When the development team opens the code and changes it, it’s not Java flags at work, it’s a release deployment. Sometimes, release deployment is chosen over feature switches whose main drawback is a higher level of complexity.
There are two ways to prevent feature switches from becoming unmanageable:
1. Prevent feature flag coupling. This means all values of feature toggles should be put into a particular class. That class will work as a single source of truth. It gives greater freedom and flexibility since it is possible to replace feature toggles storage with a database. It is also possible to implement switching flags in runtime.
2. Extracting feature toggles in Spring Boot. When there is a separate bean for all feature toggles, it is possible to insert Spring flags from the application.properties file through the @ConfigurationProperties annotation.
Spring Boot is an open-source framework based on Java. This project is built on the Spring framework and allows running various types of applications more swiftly and simply. Some remarkable Spring Boot features are:
As was mentioned before, feature toggles allow web developers to disable some functions of a web application in development. The best thing about Spring toggle is that developers need not redeploy the app or even change the code. Some feature toggles work globally, so when you configure them, they stop or start working for the whole application, but some of them can be disabled or enabled per request or per user. The development process requires using the simplest approach to resolving a problem. Feature toggles can come in handy because using them removes some unnecessary complications.
Smartly used feature toggles can stabilize the development process, while misusing them can add even more complication and trouble. Developers should know what they are doing and why.
Feature flags may be used in the following scenarios:
1. Nontrivial features that are used in trunk-based development. When frequent integration is required, sometimes it is not possible to release some bits of functionality. The use of feature flags can help to proceed with release without making changes available until they are complete.
2. A/B testing. When using feature switches, it is possible to release different solutions to a single problem and see what works best.
3. Canary releasing. The release of new features may be gradual, starting with a small group of users and continuously expanding, if the features behave correctly. That can be done using feature toggles.
4. Feature flags can be used to toggle the right setup for the right environment.
There are many ways to implement feature toggles, but the most common is to activate one or another implementation of some interface. Which depends on the value of the feature flag.
1. application.yml and @ConditionalOnProperty
It is very convenient to use application.yml for feature flags in Spring Boot apps. This file usually defines the configuration of an application and simultaneously can be a perfect place for feature toggles:
The next step requires turning on some implementation options of the feature, depending on the flag’s value. @ConditionalOnProperty annotation is used for this.
If the feature-flags.is-new-books-service-enabled value is -false, or there is no such flag in the configuration, an object from the class BooksDefaultService will be created. For the -true value, an object from the class BooksNewService will be created. This is what those classes look like:
Now, it is possible to use an object of BookService interface with actual implementation (polymorphism in action):
Sometimes, there is a need to turn off the controller itself. It is done the same way through the @ConditionalOnProperty annotation:
That way, if the value of feature-flags.is-new-books-service-enabled is -false, or such a flag doesn’t exist in application.yml, the request /books will return the 404 error.
It is not only convenient but also important to encapsulate properties of feature toggles in an object that will be registered in the Spring application’s container. For doing this, the developer needs to include the dependency spring-boot-configuration-processor:
Now, it is time for class with field flags:
For Spring to gather object from the class FeatureFlags with properties from application.yml, it is necessary to do the following:
So now it is possible to use the object from the class FeatureFlags as a bean through Spring dependency:
Feature flags often need to be adjusted and modified during the run of the app. One way to do this is through the Configuration Server. Configuration Server is a separate Spring Boot application that provides HTTP resource-based API for the main app to request its configuration. A simple Configuration Server looks like this:
It’s necessary to add a dependency:
A feature flag information can be stored in a database. Let’s consider the example of MySQL by creating a properties table with a structure like this:
It is necessary to add dependencies to work with a database:
Then, feature flags are added into the table:
Configuration Server’s application.yml looks like this:
Through HTTH, the main app will receive feature flags from the Configuration Server if the following dependency is added:
Also, it is needed to add the following bootstrap configuration:
Now it is possible to store flags in a database and load them to the main app at the start.
Now, what if the app is already running and some feature needs to be activated? Spring Actuator will help. First, it is necessary to add a dependency:
Auto-configuration of the Actuator’s refresh endpoint will be used via JMX, but it is possible to use it via HTTP:
For refreshing properties of flags, @RefreshScope annotation should be added:
Now it is possible to summon new values of flags through POST /actuator/refresh.
The diagram below presents the described architecture.
How will the implementation change? Beans are created when the app launches with the help of the annotation @ConditionalOnProperty, and they won’t change after the refresh. The problem can be solved with the help of @PostConstruct, the same @RefreshScope annotation, and the Proxy pattern:
Frequently, new functions are not only about the back-end changes. Feature flags should be used for the front-end as well. To do this, it is enough to use an additional endpoint GET /feature-flags:
Now you can see that the Spring framework has simple and flexible tools used to work with feature toggles. Web developers don’t need to use any additional libraries since Standard Spring Boot features and other ready-to-use Spring projects (Spring Actuator, Spring Cloud Config Server, etc.) cover all their needs. You can check the source code here.
Making new features visible to a limited number of users allows collecting feedback from the users in the early stages. It empowers the development team to make adjustments and changes before releasing a web application. If some new features are still too early to release, developers can turn them on just for themselves to try, test, and adjust. This helps ensure a flawless release.
The feature flag technique makes software development more stable, quick, and controllable, and helps resolve several major troubles in production release, thus reducing the development costs for the web application owner. Regular high-quality software feature releases are vital for a good user experience and holding the users’ attention.
If there is a project you are considering, our expert team can help bring your idea to life and ensure that it evolves through seamless feature releases.