Being Professional
Published in

Being Professional

Type Safe Feature Toggles Using Properties in Spring Boot

What are feature toggles?

Feature Toggles (often also referred to as Feature Flags) are a powerful technique, allowing teams to modify system behavior without changing code.

- Martin Fowler

Feature toggles is a mechanism by which one can modify the system behavior by enabling or disabling the feature toggles as required. It’s also a great way to keep certain features enabled in certain environment and keep them disabled in other environments to minimize any impact on the system failures.

It helps release half baked functionality in to the production without worrying about it’s impact on the system, it also helps hide functionality until it’s ready.

There are different types of feature toggles which have different use cases. Read more: https://martinfowler.com/articles/feature-toggles.html

Do you need a feature toggle tool/library?

Honestly, it depends on your use case. If you want features like

  • Support for multiple source like property files, database, files etc.
  • User interface to toggle feature toggles
  • REST API to toggle feature toggles

then you can go for a dedicated tool/lib like togglz (https://www.togglz.org/)

But otherwise if your use case is very simple, you probably don’t even need a third part tool or lib. You can implement your own feature toggle framework which works with property files in relatively very short time.

Implementation

TLDR

We would be using spring features like @ConfigurationProperties, @ConfigurationPropertiesBinding, @EnableConfigurationProperties

Toggle Properties

If specified using a common readable prefix, all the feature toggles can be represented using a Java POJO.

feature.toggles.showFormatted = false
feature.toggles.debug = true

The feature toggle class

This class represents a single toggle, and has methods isEnabled and isDisabled which can be used to check if toggle is enabled or disabled. Another convention which can be used for these methods is isActive and isInactive. The choice of these methods also depends on what convention is followed for properties in application.properties.

e.g. if the toggle property name is debug then both isEnabled or isActive are relevant. But if the toggle property name is enableDebug, then isActive reads better than isEnabled.

FeatureToggle.java

package beingprofessional.featuretogglesdemo.featuretoggles;

public class FeatureToggle {

private final boolean value;

public FeatureToggle(boolean value) {
this.value = value;
}

public boolean isEnabled() {
return value;
}

public boolean isDisabled() {
return !value;
}
}

FeatureToggleConverter

Then we introduce a converter which converts boolean feature toggle properties from the property file into the FeatureToggle class we created above

package beingprofessional.featuretogglesdemo.featuretoggles;

import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@ConfigurationPropertiesBinding
@Component
public class FeatureToggleConverter implements Converter<String, FeatureToggle> {

@Override
public FeatureToggle convert(String isEnabled) {
return new FeatureToggle(Boolean.parseBoolean(isEnabled));
}
}

Make sure to mark the class with @Component

FeatureToggles

This class holds reads all the toggle properties under a common prefix into a class.

For this we make use of @ConfigurationProperties Refer: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-typesafe-configuration-properties

Also notice that we have made the FeatureToggles class as an immutable class, so that the toggle values are not modified accidentally. For this we have made use of @ Refer: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-constructor-binding

package beingprofessional.featuretogglesdemo.featuretoggles;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;

@ConfigurationProperties(prefix = "feature.toggles")
@ConstructorBinding
public class FeatureToggles {
private final FeatureToggle showFormatted;
private final FeatureToggle debug;

public FeatureToggles(FeatureToggle showFormatted, FeatureToggle debug) {
this.showFormatted = showFormatted;
this.debug = debug;
}

public FeatureToggle showFormatted() {
return showFormatted;
}

public FeatureToggle debug() {
return debug;
}
}

Enable the FeatureToggles configuration properties

Note: When using @ConstructorBinding, We need to explicitly register the FeatureToggles class with the spring context using @EnableConfigurationProperties

package beingprofessional.featuretogglesdemo;

import beingprofessional.featuretogglesdemo.featuretoggles.FeatureToggles;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@EnableConfigurationProperties(FeatureToggles.class)
public class FeaturetogglesdemoApplication {

public static void main(String[] args) {
SpringApplication.run(FeaturetogglesdemoApplication.class, args);
}

}

Usage

The feature toggles framework is now ready and can be used in the code. Example usage.

package beingprofessional.featuretogglesdemo.controllers;

import beingprofessional.featuretogglesdemo.featuretoggles.FeatureToggles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
private final FeatureToggles featureToggles;

@Autowired
public HelloController(FeatureToggles featureToggles) {
this.featureToggles = featureToggles;
}

@GetMapping("/hello")
public String hello(@RequestParam String name) {
if (featureToggles.showFormatted().isEnabled()) {
return String.format("<h1>Hello, %s</h1>", name);
} else {
return String.format("Hello, %s", name);
}
}
}

Refer Code: https://github.com/sujeet100/featuretogglesdemo

--

--

--

Learning to become a professional one step at a time

Recommended from Medium

AlgoTogether 算法学习小组(第二期招生)

State time machine with replay_bloc

Git commands

Why C# and .NET Core are the Next Big Thing

Power Platform Assessment: Data Gateways

Day 7 of 31-Day May LeetCode Challenge

Microsoft Remote Desktop Mac 10.7

Rails is Magical? Maybe You’re Scared

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Sujit Kamthe

Sujit Kamthe

Software Craftsman | Lead Consultant @ Thoughtworks

More from Medium

Arranging Java Records

XML Parsing using JAXB

The proxy pattern in Microservices

Start with Spring Boot