Spring Boot Toggle Feature using Togglz

  • Feature toggle is a design pattern used to hide, enable or disable a feature during runtime.
  • For example, during the deployment, a developer can disable the feature in the code which is released to production and enable it later in the next iterations when its 100% ready or enable the feature for testing to limited set of users , profiles or certain geographic location.
  • It gives the power to reduce risk, iterate quicker, and gain more control and allows you to decouple feature rollout from code deployment.
  • This separation allows you unprecedented control on who sees what and when, independent of release.
  • Feature flagging is a core component of continuous delivery that empowers software organizations to release quickly and reliably.
  • While there are many ways to achieve this but in this blog we will see how this can be done in Spring Boot microservice using Togglz library
  • The Togglz library provides an implementation of the Feature Toggles design pattern.
  • To demonstrate this feature we will build the following use case
    • Expose a Product API , which will return product information
    • When the festive period is on , then enable the feature to show discounted price
    • Add the code for new product but enable it only when its ready
  • To use Togglz library include the following dependency in pom.xml file
<dependency>
<groupId>org.togglz</groupId>
<artifactId>togglz-spring-boot-starter</artifactId>
<version>${togglz.version}</version>
</dependency>
  • Togglz library also comes with a user interface and to enable it , add the below dependency
<dependency>
<groupId>org.togglz</groupId>
<artifactId>togglz-console</artifactId>
<version>${togglz.version}</version>
</dependency>
  • The main interaction with the Togglz library is done using the FeatureManager class, which is injectable and configured automatically.
public enum ProductFeatureFlag implements Feature {

    @EnabledByDefault
    @Label("Additional information about a book")
    ADDITIONAL_INFORMATION,

    @Label("Price during festive period")
    FESTIVE_DISCOUNT,
}
  • The other way to define the feature toggle is defining it in the application.properties file and accessing with new NamedFeature(“NAME”)
togglz.features.NEW_PRODUCT.enabled=true
togglz.feature-enums=com.raj.nola.togglz.config.ProductFeatureFlag
  • When ADDITIONAL_INFORMATION flag is active then we need to show additional info and when FESTIVE DISCOUNT is active then the discounted price should be shown
@GetMapping
@RequestMapping("/product")
public ResponseEntity<JsonNode> getProduct() {

ObjectNode product = objectMapper.createObjectNode();
product.put("productID", "NB101");
product.put("productName", "NoteBook");
product.put("price", 5.00);
product.put("description", "Good Note Book");
product.put("availabileFrom", "30-Jan-2020");

if (featureManager.isActive(ProductFeatureFlag.ADDITIONAL_INFORMATION)) {
product.put("additionalInfo", "8\" x 10-1/2\", college-ruled notebooks fit more writing per page than wide-ruled sheets; each notebook provides 70 double-sided sheets with red margin lines");
}

if (featureManager.isActive(ProductFeatureFlag.FESTIVE_DISCOUNT)) {
product.put("price", 4.00);
}
return ResponseEntity.ok(product);
}

When NEW_PRODUCT flag is active then the new endpoint should be shown, this is configured using application.properties

togglz.features.NEW_PRODUCT.enabled
@GetMapping
@RequestMapping("/productV2")
public ResponseEntity<JsonNode> getBookWishlist() {

if (featureManager.isActive(new NamedFeature("NEW_PRODUCT"))) {

ObjectNode product = objectMapper.createObjectNode();
product.put("productID", "NB102");
product.put("productName", "B5 Spiral Notebook Lined");
product.put("price", 10.00);
product.put("description", "Spiral Ruled Journal");
product.put("availabileFrom", "1-Feb-2020");
product.put("additionalInfo", "B5 Size: 26cm x 18cm / 10.3\" x 7.2\", 70 sheets (140 pages) per notebook");

return ResponseEntity.ok(product);
}
  • So what we have is a Product API , with additional information feature ON by default.
  • Price for Festive discount disabled and controlled by Feature Flag
  • A New V2 API of Product controlled by Feature Flag but disabled
  • Togglz library also comes with a web UI and its configured to run on the same part in which service is running . This is defined in application.properties
togglz.console.enabled=true
togglz.console.path=/togglz-console
togglz.console.secured=false
togglz.console.use-management-port=false
  • API by default will return following output
  • If you turn on festive discount feature and hit the API , you will notice the new price is shown now.
  • As the NEW Product API is not enabled, when you hit the API you will not get any response.
  • Once the flag is turned on , and then if you hit the endpoint again. It will return a response.
  • If you click on Actions for the feature, it will help you set an Activation strategy for the API like enabled it on a certain date or only for a certain user
  • Using the default configuration, Togglz manages the state of a feature toggle with an in-memory based solution.
  • There are out-of-the-box integrations for feature state management with a JDBC data source and MongoDB for maintaining the state.

Thanks and share your comments / feedback

9 thoughts on “Spring Boot Toggle Feature using Togglz

  1. Great write up Rajesh!

    Togglz looks like a nifty tool. But by itself, it will not prevent ‘if/then/else’ to pop a bit here and there in the code.
    I would not be too worry about it since togglz would scoop all the occurrence of that type of logic.

    I had decent success using in controller only, and finding OK places in the UI ( like the UI-component for the page level )

    But I think it’s still some type of technical debt.

    Martin Fowler wrote has a great in-dept example of bringing that to the next level with an extra serving of patterns ( Of course… the guy sells pattern! what do you expect :p )

    I actually never implemented something as he describes, but Ihis example makes senses, basically the point of code that needs to do “IF FeatureA THEN” is reworked with a Strategy-like pattern, so all the conditional logic is one place rather than scattered in the rest of the code.

    From personal experience, it becomes important when you have 10-ish feature, and that they start to influence each other. If the logic starts to be “on/off except if that other thing is also off”… it’s when it needs to be abstracted away somewhere else.

    1. Hey Antoine,

      features influencing each other is a common mistake when using feature toggles. In cases like these people should reflect their workflow. A tool can only be as good as the people using it.
      In general, feature toggles should live as short as possible. Turn the feature on on your test stage. If it works as expected, turn it on on the live state. If everything is fine, deploy another change which removes the if-else statements and the toggle itself.

      Best regards
      Bennet

  2. Great write up Rajesh!

    Togglz looks like a nifty tool. But by itself, it will not prevent ‘if/then/else’ to pop a bit here and there in the code.
    I would not be too worry about it since togglz would scoop all the occurrence of that type of logic.

    I had decent success using in controller only, and finding OK places in the UI ( like the UI-component for the page level )

    But I think it’s still some type of technical debt.

    Martin Fowler wrote has a great in-dept example of bringing that to the next level with an extra serving of patterns ( Of course… the guy sells pattern! what do you expect :p )

    I actually never implemented something as he describes, but Ihis example makes senses, basically the point of code that needs to do “IF FeatureA THEN” is reworked with a Strategy-like pattern, so all the conditional logic is one place rather than scattered in the rest of the code.

    From personal experience, it becomes important when you have 10-ish feature, and that they start to influence each other. If the logic starts to be “on/off except if that other thing is also off”… it’s when it needs to be abstracted away somewhere else.

  3. Hey,

    I’m glad you like togglz. Please raise an issue if you need something or something doesn’t behaves as expected 🙂

    An addition to your nice write up: Besides the togglz-console, you can also switch feature toggle states via Spring Boot actuator endpoint.

    best regards
    Bennet

Leave a Reply