14 Feb 2017

Implementing feature flags in single page apps, using React and Redux Saga

Built on frameworks like React, Angular, and Ember, single page apps (SPA) are becoming the new norm for modern applications. They center around dynamically updating a single HTML page via AJAX and HTML5 to deliver a more fluid and faster user experience. This introduces some new complexity when it comes to controlling access to front-end features, specifically via feature flags.

Feature flags (toggles) are used to gate access to particular code snippets, allowing you to control a feature’s rollout, target specific users, and kill a feature in production. The challenge with feature flagging single page apps is handling the state transformations (the changes in a webpage’s DOM) in a way that maintains performance and a fluid user experience.

This article discusses how to feature flag in a React single page app to show best practices. More specifically, we demonstrate feature flagging using LaunchDarkly’s JavaScript SDK.

Feature Flagging in Single Page Apps

With the help of React Router, creating a single page application can be a very quick and easy process, allowing developers to minimize risk and test features without degrading the user experience. We use Redux Sagas to handle asynchronous actions, which is perfect for integrating our app with the LaunchDarkly JavaScript SDK.

Feature Flags

In our app, we use two feature flags, user-type and header-bar-color. The user-type feature flag controls the content that is displaying depending on the group of current logged in user, while header-bar-color returns a hex code to toggle the color of the navigation bar.

An implementation of header-bar-color might look something like this:

Integrating Feature Flags with Redux Sagas

We handle the asynchronous process of requesting a LaunchDarkly feature flag by using Redux Sagas. The workflow begins in the App component of our SPA, where we dispatch an action to initialize the LaunchDarkly client.

Then, we can use a saga as middleware to wait for an initialization request to be received, using redux-saga’s takeEvery module, which will call an effect, initLD.

The effect will call getLD, a function which creates a promise, waiting for the LaunchDarkly client to be ready for flag requests. Since the user is anonymous, we can generate a random token to be used as their key.

Once the client is ready, the effect will send the action off to our reducer, to store the client and current feature flag state in props.

Now that the LD client is initialized, and stored in our props, we can define a process to update our flag whenever the current user changes (logging in or out, for example). We take advantage of the fact that we’re already using sagas to asynchronously handle user authentication. When logging in, the authorize effect is called to ensure the login data is correct. When authorization is complete, we’ll make a call to idLD. This will identify a new user in our LaunchDarkly client, and send the correct flag to the reducer for our newly logged in user. Logging out works in a similar fashion. (Note: We make use of some utility functions defined in auth, which return user information from our local storage.)

So, what do we do with the flags stored in our props? Well, in our Home component, we’ll render a different page depending on the flag that was received. In our case, if a fallback flag is received, the “Anonymous” page will be shown no matter who is logged in.

Meanwhile, every time a page is loaded, the Nav component takes in the headerColor prop and changes the background of our navbar to said color.

See it in action

What’s next?
There are many ways to feature flag within a single page app, depending on your case and the complexity of your features. You can also check out this repo by TrueCar, which provides another avenue for feature flagging in React Redux.

Want to try out this feature flagging in React for yourself? Check out the open source repo!

—-

Primary Contributor:  Arnold Trakhtenberg, Engineering Content Consultant at LaunchDarkly

14 Oct 2016

To Be Continuous: Specialization In Organization Design

In this episode, Edith and Paul dive into the question of specialization. They discuss the pros and cons of working with specialists vs. generalists, and how your decisions in this area can have a wide ranging impact on your product and company.  This is episode #25 in the To Be Continuous podcast series all about continuous delivery and software development.

Continue reading “To Be Continuous: Specialization In Organization Design” »

05 Apr 2016

To Be Continuous: Open Source Economics

In this episode of To Be Continuous, Edith and Paul are joined by Sean Byrnes, CEO of Outlier.ai, and Nadia Eghbal. The group discusses open source economics, and examines several potential evolutions of adding money to the open source equation. This is episode #17 in the To Be Continuous podcast series all about continuous delivery and software development.

Continue reading “To Be Continuous: Open Source Economics” »

17 Jan 2016

To Be Continuous: How Do You Deal with Your Data?

In this episode, Edith and Paul are joined by Peter Van Hardenberg from Heroku. The group discusses how continuous delivery works with and against organizational structure, databases, and the pricing of your product. This is episode #11 in the To Be Continuous podcast series all about continuous delivery and software development. Continue reading “To Be Continuous: How Do You Deal with Your Data?” »

08 Dec 2015

Feature Toggles at Tout

How Tout uses feature toggles in their development process, guest post by Javid Jamae, Principal Engineer (Growth at Tout).

Tout is a video platform for media brands and content publishers. We have video players on hundreds of prominent high-traffic media websites and blogs across the United States. Using our video marketplace, websites can show premium video content from producers such as Time, Yahoo, Condé  Nast, The Wall Street Journal, ESPN, and dozens of others. The sites can also let their journalists and authors capture their own video content using our Android and iOS apps, and then play their content on their sites.

The way our service works is that we provide a Javascript embed code that our partner sites place within their website template. When their page loads, we inject our video players into various parts of the page. Deciding everything from where the video players placed, what video content it has, and how it appears can be decided on the server side, thus minimizing configuration and code changes for our customers.

In the early days, we only had a few sites using our new products. To keep things simple, we kept most of our product configuration in the code and consistent across all of our partner websites. When we wanted to make a change, we would negotiate with all of them before rolling out a new feature. This was manageable because there was little to no variability and notifying  individual partners of changes was easy.

As our customer base grew, we found it increasingly difficult to maintain a single product configuration, so we introduced a way to configure products differently for each partner website. But, due to the nature of being an embedded product, we started finding it difficult to test changes internally and to demonstrate changes to our partners.

We did internal testing using a web debugging proxy software called Charles. We would deploy an updated version of our code to our staging (i.e. internal test) environment, then we would configure Charles to proxy our production server to our staging server on the machine we were testing on. Though there are a few snags with this process, it works relatively well overall. The problem with this approach is that it only works for internal testing.   

Our customers often wanted to preview new changes to their site before we rolled them out so that they could do their own verification and training. As the demand for customer previews increased, we started looking into feature toggles as a solution.

Conceptually, feature toggles are simple, you just keep the old version of your code in place, but wrap it in a conditional clause that does the new thing if the feature is enabled:

Since we are using Ruby on Rails, we started by using a Ruby library appropriately called ‘feature’. The feature library is an open source library hosted on Github. The great thing about this library is that it enabled us to create feature toggles in our code within minutes.

Using this library had several downsides as well. Since it’s just a library, it has no user interface for creating or modifying feature toggles. It also has no functionality for passing in feature toggles from web browsers using request parameters or cookies, which is tremendously useful for testing a specific state of your toggles. Another thing that is missing is metadata around when and who modified the state of the toggles, which is really useful for debugging and forensic purposes. Nevertheless, with a bit of work building out those tools, the feature library was great for getting up and running and we were able to deploy our code to our production with a new feature toggled “off” and then enable it for testing or demo purposes.

feature switch

After starting to use feature toggles, we realized several unintended benefits. First, if we found any issues with the new version of the code, we could merely roll back to the old version by switching a toggle. We no longer needed to do roll-back or roll-forward deployments to undo a mistake in production.

Another great benefit was that it minimized environment contention. Since our team is still relatively small, we only have one test environment. By using feature toggles, everybody could merge and deploy their changes to the staging environment and just toggle “on” the features that they want to test by setting cookies in their browser.

We also started using feature toggles as a way to do zero-downtime feature cutover. Since we’re using a microservice architecture, we have multiple systems that all talk to one another. Previously, if we needed to roll out a new feature that required communication between multiple systems, we would have to bring down all of the related systems and deploy all of the appropriate code changes before bringing the systems back up. But with feature toggles, we were able to deploy each system code change when it was ready and then just synchronize toggling the new functionality on. Effectively, this eliminated the need to have complex blue-green deployments since we just managed it all with feature toggles.

However, using toggles comes at a cost, though I feel like the cost is definitely justified. First, not all of our developers were thrilled about having temporary if/else statements littered throughout the code. They felt that this added extra complexity in the code and in the unit/integration testing effort. We started developing some good best practices around where to put the feature toggles and updated our development process to include the proper removal of features that had already been rolled out. While unit testing did become more complex, the overall complexity of our process was simplified. We no longer required as many unnecessary feature and merge branches and the deployment and process became simpler as I mentioned earlier.

All in all, I’d say that using feature toggles has been a great tool in our tool belt and has had significant positive benefits to our development process. Though we used an open source library and grew the tools that we needed around it, tools like LaunchDarkly (which didn’t exist when we got started) would quite possibly have gotten us to where we needed to be much faster by providing us with all the tools that we had to build from the ground up and the support that we didn’t have.