1/12/2020 by jdabulis

Feature Toggles For The Web

The Concept

Suppose you have a real estate website with a Mortgage Calculator form that asks the user to enter the loan amount, loan term and interest rate. When this data is submitted, the server computes an amortization schedule and other information you want to display to the user.

Now suppose you want to change the behavior of this application so that it also asks the user for their credit score. Instead of asking them to input an interest rate, the application should fetch the most current loan interest rates from some particular mortgage lending company’s web service for the given term and credit score.

One way to manage adding or modifying a website feature is to fork or create a new branch of your code repository and to implement the changes in this new version branch. Once the changes have been thoroughly tested locally in development, you merge the changes into back into the trunk, build the application, and deploy it to the production server. This is build-time application behavior control.

But suppose there are some problems or unforeseen complications with consuming the mortgage company’s (“third party”) service. Here are a few potential scenarios that would cause problems:

  • The third party service could become unavailable for a period of time
  • The third party service could prove unreliable (bugs were discovered)
  • The third party service could announce that they’re changing the API.
  • There could be a bug in your code that wasn’t discovered in test.

What you’d like to be able to do is switch to the new feature, but keep the original code dormant so that you could revert back to it without rebuilding and redeploying the application. This decision to execute the original code or the new code depends on whether a toggle switch is off or on, and is made at run-time, not build-time. Here is an article that briefly discusses how one might assemble open source components for this purpose for a PHP site.

Feature toggles can also be handy in other situations:

  • Trying out an experimental change or feature to your UI, subject to public feedback
  • Exposing temporary, or time/schedule-sensitive behaviors to your users
  • Providing an “emergency shut down” of recently added changes, completely turning off new code if necessary, on-the-fly, without any need to rebuild or redeploy.

Toggle Characteristics

A toggle to be used for any or the purposes described above should have the following characteristics:

  • A unique identifier (name or numeric id)
  • A default value (off or on)

In more advanced toggle systems, toggles can have additional characteristics such as:

  • Date/Time when the toggle should be turned On/Off
  • Default toggle settings for specific users or groups of users.
  • Toggle groupings so that related or dependent features can be turned on or off as a set

Toggle Control System

A toggle control system is an application unto itself, integrated with your web application. It supports the following use cases to your developers, testers, site administrators, and the web application itself:

  • (For Developers) Be able to mark code that should execute when a particular toggle is turned on.
  • (For Testers) Be able to compare and test the site with particular toggle(s) turned on vs. off.
  • (For Administrators) Be able to turn toggles on or off in production.
  • (For Web Application) Execute code conditionally based on the run-time value of toggles.

There are situations where feature toggles could be used but should not be.

Additionally, there are situations for which feature toggles cannot be used at all.

Implementation

First you’ll need to store the On/Off status for all toggles so that both the web application and the toggle control system have access to these settings. While you could use a database, especially in support of an advanced toggle control system, a configuration file will suffice, and will provide a very nice and easy way to document and maintain all the toggle settings.

For example:

{  "Toggles": 	[
         [ 0, true ], /* if Toggle #0 is true = Show the new UI */
         [ 10, true ] /* if Toggle #10 is true = New Mortgage Calculator */
    ]
}

Next, you’ll need a secured toggle “admin page”, or at least a url that can be used by a tester to change (i.e. override) the value of a production toggle-- just for them-- without affecting the behavior of the application to the rest of the world.

For example, navigating to

www.mysite.com/toggle-admin/ON/10 or

www.mysite.com/toggle-admin/OFF/10

routes to a controller that should be designed to challenge the user for credentials, and if these are correctly provided, the controller can override value of toggle #10 in the admin user’s Session (or cookie). If incorrect “logon” credentials are provided, the application can log the event and respond with a 403 status code or something.

Next, you’ll need to add a utility class that can get the current value of a given toggle at run-time. This class could first check the user’s Session for value of the toggle, and if it’s not found, read the value from the config file. It is also very useful to implement the controller such that navigating to www.mysite.com/toggle-admin/ without any parameters will display a table of which toggles are on or off for the public compared to those that are overridden for the current Session.

All the tester needs to do to “restore” the toggle values back to their settings as defined in the config file is to close and reopen their browser.

Finally, the developer uses the utility class to control the behavior of the application by testing the value of a toggle at run-time. In an ASP.NET MVC View, for example, one might write some Razor code such as:

@{ if (Toggles.Get(NEW_CALCULATOR_TOGGLE)) {
    <li><a href="/calculator" class="nav-link">Mortgage Calculator</a></li>
} else {
    <li><a href="/newcalculator" class="nav-link">Mortgage Calculator</a></li>
}

Where NewCalculatorController provides the entry point for all the new calculator views and integration logic.

Emergency? Shut it Down!

To turn the new feature off, we only need to change the config file:

{ "Toggles": 	[
         [ 0, true ], 
         [ 10, false ]
  ]
}

and upload this single file to the production server.

Removing Toggles

Perhaps after some time when the new feature is considered mature and there haven’t been any reports of problems, the develop should remove the toggle by first replacing the code above with a simple link:

    <li><a href="/newcalculator" class="nav-link">Mortgage Calculator</a></li>

Then, of course, the old, unused controller should be removed. The entry for the toggle in the config file should also be removed.

Conclusion

We think feature toggles, if used sparingly and carefully, are a useful tool in simplifying the deployment process as well as reducing the risk of exposing unexpected behaviors. We automatically bake this capability into our client’s dynamic web applications. We can also take an existing site and put such a system in place.

© Lognosys LLC. All rights reserved.