Article

8min read

How to Implement Feature Flags in Java

In this article, we’ll cover how to implement feature flags in Java using our Java SDK and also discuss other open-source Java frameworks available on Github. If your are using the Spring framework, this article will suit you well.

Overview of the feature flag pattern

Feature flags are a powerful software development tool that turns certain functionalities on and off without the need to deploy new code, and without any service disruptions. Feature flags can be used for a wide range of purposes, from kill switch to targeted releases (ex: ring deployments, canary deployments), through feature testing. Thus, a feature flag ranges from a simple IF statement to more complex decision trees, which act upon different variables.

AB Tasty offers an enterprise-grade feature flag management platform that keeps you in control of your release strategies.

As its core, it provides a Decision API to assign and retrieve feature flag values for your users (e.g. what value a flag should be for a specific user), so you don’t have to mess with complex configuration files or manage a dedicated infrastructure to store all the different flag values.

The “Decision” part in the name refers to built-in intelligence that is key to maintain flag values consistency between different user sessions or for instance when an anonymous users gets authenticated to your application.

White this REST API is language-agnostic by design, we provide several server and client-side SDKs. Here, we’ll discuss the Java SDK that includes preconfigured methods to implement the Decision API. Refer to our developer documentation for more details.

Setting feature flags with AB Tasty Java SDK

Using our cloud-based feature management service is a 2- step process. First, in your codebase, you wrap your features once with flags using methods from the Java SDK. Once this is done, you remotely configure your flags (values, segments…) from the dashboard. Let’s see both steps in details.

Setting up the Java SDK

Installation and initialization

First, you need to add the Java repository to your dependency manager. You can use Maven or Gradle build tools to do so:

<pre><code class="language-maven line-numbers"><!--
// Gradle
maven { url 'https://abtasty.jfrog.io/artifactory/flagship-java' }

// Maven
<repositories>
    <repository>
        <id>com.abtasty</id>
        <url>https://abtasty.jfrog.io/artifactory/flagship-java</url>
    </repository>
</repositories>
--></code></pre>

Then, import the Java SDK using either Maven or Gradle dependency management:

<pre><code class="language-maven line-numbers"><!--
// Gradle
implementation 'com.abtasty:flagship-java:1.0.0'

// Maven
<dependency>
    <groupId>com.abtasty</groupId>
    <artifactId>flagship-java</artifactId>
    <version>1.0.0</version>
</dependency>
--></code></pre>

To initialize and start the SDK, simply call the start function of the class, in the most appropriate location for your application. You need to pass two parameters: your environment id and your API authentication key. Both values are available from the user interface (UI), once you are logged in.

<pre><code class="language-java line-numbers"><!--
Flagship.start("YOUR_ENV_ID", "YOUR_API_KEY");
--></code></pre>

The start method also accepts a third argument to create a custom configuration, ex:

<pre><code class="language-java line-numbers"><!--
Flagship.start("YOUR_ENV_ID", "YOUR_API_KEY", new FlagshipConfig()
    .withFlagshipMode(Flagship.Mode.DECISION_API)
    .withLogManager(new CustomLogManager())
    .withLogLevel(LogManager.Level.ALL)
    .withTimeout(200));
--></code></pre>

Creating a new visitor

Next, you’ll have to create a new visitor.

The visitor instance is a helper object that lets you manage the context and campaigns for a user identified by a unique ID.

The user context is a property dataset which defines the current user of your app. This dataset is sent and used by the Decision API as targeting criterias for campaign assignment.

For example, if you want to enable or disable a specific feature based on a VIP status, you would pass this attribute as a key-value pair in the user context so that the Decision API can enable or disable the corresponding feature flag for the user.

<pre><code class="language-java line-numbers"><!--
Visitor visitor = Flagship.newVisitor("YOUR_VISITOR_ID", new HashMap<String, Object>() {{
    put("isVip", true);
--></code></pre>

The first parameter of the method is the Unique visitor identifier, while the second is the initial user context.

You can also update the visitor context when required. The following method from the Visitor instance allows you to set new context values matching the given keys.

<pre><code class="language-java line-numbers"><!--
Visitor visitor = Flagship.newVisitor("YOUR_VISITOR_ID", new HashMap<String, Object>() {{
    put("isVip", false);
}});

visitor.updateContext("isVip", true);
--></code></pre>

Managing feature flag assignment

The synchronizeModifications() method of the visitor instance automatically calls the Decision API to run feature flag assignments according to the current user context.

<pre><code class="language-java line-numbers"><!--
Visitor visitor = Flagship.newVisitor("YOUR_VISITOR_ID")
visitor.updateContext("isVip", true)
visitor.synchronizeModifications().whenComplete((instance, error) -> {
    // Asynchronous non blocking call
    // Synchronization has been completed. Do stuff here...
});
--></code></pre>

Once the campaign has been assigned and synchronized, all the modifications are stored in the SDK. You can retrieve these modifications using the getModification method from the Visitor instance. It retrieves a modification value by its key. If no modification matches the given key or if the stored value type and default value type do not match, default value will be returned.

<pre><code class="language-java line-numbers"><!--
Visitor visitor = Flagship.newVisitor("YOUR_VISITOR_ID")
visitor.updateContext("isVip", true)
visitor.synchronizeModifications().whenComplete((instance, error) -> {
    Boolean displayVipFeature = visitor.getModification("displayVipFeature",  false);
});
--></code></pre>

The getModification method accepts a third argument, that, if set to true will automatically report on our server that the current visitor has seen this specifc variation. It is also possible to call activateModification() later.

<pre><code class="language-java line-numbers"><!--
Visitor visitor = Flagship.newVisitor("YOUR_VISITOR_ID")
visitor.updateContext("isVip", true)
visitor.synchronizeModifications().whenComplete((instance, error) -> {

    Boolean displayVipFeature = visitor.getModification("displayVipFeature", false, true); //send an activation event.

    // or

    Boolean displayVipFeature = visitor.getModification("displayVipFeature", false);
    visitor.activateModification("displayVipFeature");
});
--></code></pre>

Measuring events and metrics

Our Universal Collect protocol provides a unified hit format to send data back to our server-side solution for reporting purposes. The format of the hit is based on the Google Analytics measurement protocol. By sending hits to our platform, you can measure the impact of a feature on different metrics such as pageviews, screenviews, transactions or generic events.

To send hits, you must call the sendHit method from the Visitor instance:

<pre><code class="language-java line-numbers"><!--
// Pageview hit
Page page = new Page("https://www.my_domain_com/my_page")
visitor.sendHit(page);

// Sreenview hit
Screen screen = new Screen("screen location")
    .withResolution(200, 100)
    .withLocale("fr_FR")
    .withIp("127.0.0.1")
    .withSessionNumber(2);
visitor.sendHit(screen);

// Transaction hit
Transaction transaction = new Transaction("#12345", "affiliation")
    .withCouponCode("code")
    .withCurrency("EUR")
    .withItemCount(1)
    .withPaymentMethod("creditcard")
    .withShippingCosts(9.99f)
    .withTaxes(19.99f)
    .withTotalRevenue(199.99f)
    .withShippingMethod("1day");
visitor.sendHit(transaction);

// Generic Event hit
Event event = new Event(Event.EventCategory.ACTION_TRACKING, "action")
    .withEventLabel("label")
    .withEventValue(100);
visitor.sendHit(event);
--></code></pre>

For more details, refer to our Java SDK references.

Setting up flags in our UI interface

The first step is to sign up to our app.

You can refer to this short video that goes through all the process of a feature flag setup or read the detailed instructions below.

<p><script src="https://fast.wistia.com/embed/medias/a0r6tvay8z.jsonp" async=""></script><script src="https://fast.wistia.com/assets/external/E-v1.js" async=""></script></p>
<div class="wistia_responsive_padding" style="padding: 56.25% 0 0 0; position: relative;">
<div class="wistia_responsive_wrapper" style="height: 100%; left: 0; position: absolute; top: 0; width: 100%;">
<div class="wistia_embed wistia_async_a0r6tvay8z videoFoam=true" style="height: 100%; position: relative; width: 100%;">
<div class="wistia_swatch" style="height: 100%; left: 0; opacity: 0; overflow: hidden; position: absolute; top: 0; transition: opacity 200ms; width: 100%;"><img style="filter: blur(5px); height: 100%; object-fit: contain; width: 100%;" src="https://fast.wistia.com/embed/medias/a0r6tvay8z/swatch" alt="" aria-hidden="true" /></div>
</div>
</div>
</div>

Creating your feature flag use case

To create a feature flag from the dashboard, apply the following steps:

  • Go to the dashboard.
  • Click the + button.
  • Choose an existing project or create a new one
  • Click the “Add a use case” button.

You are presented with a list of different templates or use cases (ex: progressive rollout, A/B test…)

Choose the “Feature toggling” template.

Entering the basic information

First, you need to enter the basic information of your feature flag use case:

The feature name: use the most representative name for your feature, because this is the one you’ll need to remember in case you want to find it later.

The feature description: explain exactly what your feature deployment is about and what its purpose for your business is.

The primary/secondary metric to follow (optional) which will serve as a point of reference to analyze performance. For more information, refer to Configuring KPIs.

Defining flags

This is where you configure the flags and their values based on your different scenarios. Think of it as the config file mentioned in the first method, but that you manage remotely from the cloud. Important: flag names you specify here should match the ones used in your codebase.

Defining targeting

During this step, you can define which users will be assigned to your different flag values. This is a segmentation engine built into the platform that makes it easy to assign flags conditionally based on user traits (or attributes) that you have access to in your codebase. Refer to this article about feature flag targeting for more information. The 3 following options are available:

  • All Users if you want all your users to progressively see your feature.
  • Users by ID if you want only users with a specific ID to see your feature.
  • Key if you only want users matching this key value to see your feature.

Enabling your feature

Once you have configured your feature, it is OFF by default to allow you to check that it is correctly configured. Back to the dashboard, you can activate your feature ON when you are ready!

And that’s it. Now, provided changes to your codebase have been deployed, you can activate/deactivate feature flags, remotely change their values and have your Java Application react instantly to these changes.

Open-source feature flag frameworks for Java

For the sake of completeness, we list here open source alternatives if you are using Java. While there are pros and cons to each approach, the third-party vendor option is probably the most efficient method for large teams with evolving use cases that don’t want to deal with the challenges of an in-house system.

Keep reading: The Journey of Feature Flag Implementation (Build vs. Buy) where we discuss the pros and cons of different options when it comes to choosing between to build, use an open-source project or buy a feature flag management solution.

FF4J – Feature Flipping for Java

FF4j, is an implementation of the Feature Toggle pattern for Java. It provides a rich set of features:

  • Enable and disable features at runtime – no deployments.
  • Enable features not only with flag values but also drive access with roles and groups.
  • Implement custom predicates to evaluate if a feature is enabled.
  • Keep your code clean and readable: Avoid nested if statements but use annotations.
  • Each action (create, update, delete, toggles) can be traced and saved in the audit trail for troubleshooting.
  • Administrate FF4j (including features and properties) with the web UI.
  • Wide choice of databases technologies to store your features, properties and events.
  • (Distributed) Cache Evaluating predicates may put pressure on DB (high hit ratio).

940 stars on Github. View repository.

togglz – Feature Flags for the Java platform

Togglz is another implementation of the Feature Toggles pattern for Java.

  • Modular setup. Select exactly the components of the framework you want to use. Besides the main dependency, install specific integration modules if you are planning to integrate Togglz into a web application (Servlet environment) or if you are using CDI, Spring, Spring Boot, JSF.
  • Straight forward usage. Just call the isActive() method on the corresponding enum to check if a feature is active or not for the current user.
  • Admin console. Togglz comes with an embedded admin console that allows you to enable or disable features and edit the user list associated with every feature.
  • Activation strategies. They are responsible for deciding whether an enabled feature is active or not. Activation strategies can, for example, be used to activate features only for specific users, for specific client IPs or at a specified time.
  • Custom Strategies. Besides the built-in default strategies, it’s easy to add your own strategies. Togglz offers an extension point that allows you to implement a new strategy with only a single class.
  • Feature groups. To make sure you don’t get lost in all the different feature flags, Togglz allows you to define group for feature that are just used for a visual grouping in the admin console.

940 stars on Github. View repository.

Unleash

Unleash is an open-source feature management platform. It provides an overview of all feature toggles/flags across all your applications and services. You first need to setup an Unleash server that you self-host, and then use a client SDK to connect your application to the server. A Java Client SDK is available and provides features such as:

  • Boolean feature toggles (on/off)
  • Canary release (Gradual rollout)
  • Targeted release
  • Experimentation (A/B testing)
  • Kill switches
  • Custom activation strategies
  • Privacy first (GDPR) where end-user data never leaves your application
  • Audit logs
  • Addons integrating with other popular tools (Slack, Teams, Datadog, etc.)
  • Dashboard to manage technical debt
  • Flexible architecture and can be hosted anywhere
  • Docker image available

3,828 stars on Github. View repository.

Subscribe to
our Newsletter

bloc Newsletter EN

We will process and store your personal data to respond to send you communications as described in our  Privacy Policy.

Article

9min read

How to Implement Feature Flags in a React JS App

Feature flags, or toggles, as described by Martin Fowler are a “powerful technique, allowing teams to modify system behavior without changing code.” In other words, implementing feature flags as a set of patterns is a robust way to manage code complexity and deliver new features to users using CI/CD (continuous integration/continuous delivery) pipelines, reducing the time to value and decreasing the risk of deploying buggy, error-ridden code to production.

Feature flags are an integral part of deploying software updates via CI/CD pipelines without disrupting existing functionality. There are several ways to implement feature flags in your React apps. Let’s consider three of the most popular and common ways: 

  1. The do-it-yourself method where the developer writes the feature flag code from scratch.
  2. The use of open-source libraries that are integrated into the React Single-Page Application (SPA).
  3. Signing up with a cloud based solution (feature flag as a service).

Do it yourself: A simple and free solution

This method requires you to write code, switching feature flags on and off directly in JavaScript. By expanding on this method, let’s consider a simple use case, including code samples from a feature flag React app project, before looking at the primary pros and cons of this method.

1. Setting up the React project 

If you already have your React project set up, you can skip to the next section, “Adding new feature flags” otherwise, here is a step-by-step guide to setting up a new project. 

The reactjs.org website notes that the create-react-app is the easiest way to develop a new single-page application with React.

Therefore, use the following code to create a new boilerplate app:


npx create-react-app my-app
cd my-app
npm start

2. Adding new feature flags 

Now that we have the project created and an empty app template, let’s look at how to add a feature flag in React.

Feature flags can be stored in different places such as a database server, inside local storage, or in a cookie. In this scenario, we will store them inside local storage. 

The first step is to create a React js feature flag file with the following format used to create new features. This will act as your config file that you’ll update every time you want to turn on/off a specific feature.

Each feature flag must have a unique name that we can later call or reference in React. A short description is also needed to describe the functionality it adds and an active flag to determine whether the toggle is on or off. 

As seen from the code snippet for creating a banner flag, our flags are stored inside an array. 

To store these flags in local storage, add the following function to your app.js file and call it at the top of your feature component file.

Note: This will create 3 new feature flags if there are no feature flags created in local storage (localStorage). You also need to use the JSON.stringify () method to convert the JavaScript objects into strings as localStorage can only handle strings.

3. Adding the feature component

In order to reference these feature flags in React and show/hide features based on these feature flags, you need to create a new React component <Feature />. Define it in a file called feature.js and store it in your src folder.

This component accepts 2 props:

  1. the flag name to check against,
  2. the child content to be used (children prop).

The first step is to get the feature from localStorage and see if it is set to active or not. If the feature is active, we can render the feature; otherwise, we return null. 

This component will handle the toggling of feature flags on and off. Finally, you just import and render the component where you need.

Pros 

There are several advantages to using this method. The most obvious being the fact that when writing your own feature flag code, it is free, easily accessible, and highly available for small React feature toggle projects. 

Cons 

However, what happens when your application grows in scale, and you need to create and manage several different feature flags, both long- and short-lived? 

This is where this method’s disadvantages come to the fore. Succinctly stated, this method is difficult to scale where lots of flags are utilized. And as you can see from the code samples highlighted above, advanced features require more development work which can be challenging and complicated to maintain.

Feature flag open-source libraries for React 

The second method is to use existing libraries that you can find on Github. A simple search will lead you to multiple open-source libraries or packages to do feature flagging. Here are a few examples of these packages for React: 

Flagged, for instance, provides nice features such as:

  • Hooks API
  • High Order Component API
  • Render Props API
  • TypeScript Support
  • Zero Dependencies
  • Nested Flags

Pros

The advantages of using these open-source libraries are that they are freely available, easy to use, and quick to set up. As described above, all you need to do is consume the libraries into your application and then call the functions created in the library files, passing in variables as required and reading returned variables to understand the state of your feature flags.

Cons 

However, as with everything, there are also disadvantages to using open-source feature flag libraries. The most prominent includes the fact that maintenance and evolution are not guaranteed, and the library’s functional scope might not suit your app’s specific requirements. In both cases, a fair amount of refactoring and new code development will have to take place to maintain the existing code and add the features specific to your application.

Feature flag management platforms

The third and last way to implement feature flags in a single-page application is using a dedicated feature flag management 3rd-party service that provides a React integration.

By way of expanding on this statement, let’s look at a step-by-step guide on how to set up feature flags in our server-side solution with the React SDK. As an alternative, you can also directly call the Decision API (REST API), but for the sake of simplicity we’ll use the dedicated SDK that provides additional capabilities out of the box (ex: bucketing). The platform also provides additional SDKs for Java, Python, PHP, .Net, Go, iOS, Android, Flutter

Using our cloud-based feature management service is a 2- step process. First, in your codebase, you wrap your features once with flags using methods and providers from the React SDK. Once this is done, you remotely configure your flags (values, segments…) from the dashboard.

1. Set up the React SDK in your SPA project and wrap features with flags

Let’s use the same project that we created in the first method (Setting up the project) using our create-react-app boilerplate app.

Install the SDK using NPM or yarn.


npm install @flagship.io/react-sdk

Import the our provider from the React SDK which makes the tool’s features available to the rest of your app.  You can wrap your app directly within the app.js file.

The envID and apiKey props are required. You access them from the UI under the “Settings” section. For more information on the different props available, please refer to the API references

Then, from the React component you want to get access to your flags, import and use one of our React Hook. It gets modifications assigned to the current user as well as further functionalities, such as sending hit tracking, checking the SDK status…

2. Declare your flags in the UI and set up values

The first step is to sign up to our app. 

You can refer to this short video that goes through all the process of a feature flag setup or read the detailed instructions below.

Creating your feature flag use case 

To create a feature flag from the dashboard, apply the following steps:

  1. Go to the dashboard.
  2. Click the + button.
  3. Choose an existing project or create a new one
  4. Click the “Add a use case” button.
  5. You are presented with a list of different templates or use cases (ex: progressive rollout, A/B test…)
  6. Choose the “Feature toggling” template.

Entering the basic information

First, you need to enter the basic information of your feature flag use case:

  1. The feature name: use the most representative name for your feature, because this is the one you’ll need to remember in case you want to find it later.
  2. The feature description: explain exactly what your feature deployment is about and what its purpose for your business is.
  3. The primary/secondary metric to follow (optional) which will serve as a point of reference to analyze performance. For more information, refer to Configuring KPIs

Defining flags

This is where you configure the flags and their values based on your different scenarios. Think of it as the config file mentioned in the first method, but that you manage remotely from the cloud. Important: flag names you specify here should match the ones used in your codebase (“btnColor” in your code example above).

Defining targeting

During this step, you can define which users will be assigned to your different flag values. This is a segmentation engine built into the platform that makes it easy to assign flags conditionally based on user traits (or attributes) that you have access to in your codebase. Refer to this article about feature flag targeting for more information. The 3 following options are available:

  • All Users if you want all your users to progressively see your feature.
  • Users by ID if you want only users with a specific ID to see your feature.
  • Key if you only want users matching this key value to see your feature.

Enabling your feature

Once you have configured your feature, it is OFF by default to allow you to check that it is correctly configured. Back to the dashboard, you can activate your feature ON when you are ready!

And that’s it. Now, provided changes to your codebase have been deployed, you can activate/deactivate feature flags, remotely change their values and have your React App react instantly to these changes.

Last thoughts 

This article describes three ways of implementing feature flags in a React SPA (single-page application):

  • the do-it-yourself method,
  • using open-source libraries,
  • signing up with a dedicated feature management platform.

While there are pros and cons to each approach, the third-party vendor option is probably the most efficient method for large teams with evolving use cases that don’t want to deal with the challenges of an in-house system. For more details, read our article The Journey of Feature Flag Implementation.