Using Feature Toggle in a React application (part 2)

Zenobia Gawlikowska
EcoVadis Engineering
4 min readMar 16, 2021
Photo by Karim MANJRA on Unsplash

Continued from Using Feature Toggle in a React application (part 1).

In part 1 of this article, we discussed the prerequisites of a solid, enterprise-grade Feature Toggle solution and the implementation of a developer-friendly component, allowing for convenient testing, demonstrating clarity of intent and ease of removal when no longer necessary. In part 2, we are going to discuss integrating our Feature Toggle solution with third party providers.

Note: The ideas covered in this article have been used to implement an NPM package called featuretoggle-react which is available here: https://github.com/EcovadisCode/featuretoggle-react

As we have seen in part one, one of the requirements of an enterprise-wide Feature Toggle is to integrate with external service providers. There are many reasons for this: among other things, the Feature Toggle needs to work with many different systems and architectures and it needs to use the tools Business Stakeholders are familiar with. At the same time, any solid implementation must use a pluggable architecture, one that will allow a smooth transition between one service provider and the next, should that be necessary, with minimal changes in the frontend code. Let’s see what this all means in practice.

Working with provider APIs

1. Flagsmith

Flagsmith (formerly known as Bullet Train) is one of the providers we will take into consideration in this article. So let’s jump right into the relevant javascript API documentation¹.

A reference implementation looks like this:

Looking at the implementation, we see straight away that there are two key elements to handle here: init and onChange. The init method initializes the client, providing the environment variables and configuration, including the onChange callback, which will be called upon each Feature Flag change, whenever that happens. Later on, we will see how often we really need to be notified of changes in the state of Feature Flags. For now, let’s just take note of the basic API structure.

2. Optimizely

Now, let’s take a look at the API of another Feature Toggle provider, Optimizely².

This API is invoked by a createInstance method. The other key element is the onReady event, which is fired when the Optimizely configuration is downloaded and ready. As we can see, it is implemented as a Promise³ with a callback for a successful Promise resolution.

Creating a pluggable architecture

Just by looking at the divergent API implementations, it becomes apparent that we need to create a layer of abstraction to hide the implementation complexity, so that our code is insulated from the vendor-specific implementations. Ideally, switching from one provider to the next should be as simple as changing a const variable value.

It seems reasonable to assume that we need to implement an abstract `init` method, which will be able to accept a callback when the state has been updated. Let’s try to create something to this effect:

In order to work, this component expects a feature prop and child components able to read the state of the Feature Toggle, as we have discussed in Part 1:

The feature prop will be the feature name, as implemented in the third party Feature Toggle solution. The child <On> and <Off> components will just read the featureToggleEnabled prop that is passed into them via the React.clone method and show or hide their own child components accordingly. The remaining props to be passed to the component are the following:

  • featureToggle an array of the actual Feature Toggles and their state
  • updateFeatureToggle action to update the local state of the toggles when data is received from the remote endpoint
  • isLoaded loading state for the Feature Toggle

Those additional props will be wired using good old connect from the react-redux library:

The action creators, selectors and reducers can be very straightforward:

Actions:

Reducers:

Selectors:

Creating the adapters

What remains to be implemented, are plugins which call the actual APIs of the different service providers. As discussed above, the plugin implementation must cover the init and onChange event callback. So let’s try to write it. Here is an implementation for Flagsmith:

The plugin is responsible just for the implementation details for the Flagsmith API and passes the result to our handleChange generic callback. A similar implementation for Optimizely would look like that:

Now that the client plugins have been created, all that remains to be done is to create a Client Provider which will export the selected plugin:

Conclusion

We have thus created an abstraction layer for our Feature Toggle solution, which will allow seamless integration with different Feature Toggle Providers without any impact on the consuming code. This will provide the required flexibility and robustness of our codebase and will insulate our React components from any knowledge about where the Feature Toggle states are coming from — which is exactly what we were aiming for.

References

[1] https://docs.flagsmith.com/clients/javascript/

[2] https://docs.developers.optimizely.com/full-stack/docs/javascript-browser

[3] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

--

--