Skip to content

Instantly share code, notes, and snippets.

@asaschachar
Last active July 29, 2020 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asaschachar/1ec4ce7cf931cdaabfc11b594fd56f87 to your computer and use it in GitHub Desktop.
Save asaschachar/1ec4ce7cf931cdaabfc11b594fd56f87 to your computer and use it in GitHub Desktop.

Backend Feature Flags in NodeJS

Prerequisites

  • Node version >= 8.1
  • npm version >= 5.6

Steps

1. Create an Express Application

If you already have a NodeJS application feel free to skip to step 2. Otherwise, follow the instructions to create a new express application.

Use the ExpressJS Application Generator to create a new Express app named node-feature-flags:

npx express-generator node-feature-flags

Change to the newly created application directory:

cd node-feature-flags

Install dependencies with:

npm install

Run your newly created application with:

DEBUG=node-feature-flags:* npm start

And see your application running by opening a browser to localhost:3000.

2. Setup the Feature Flag Interface

Create a free Optimizely Rollouts account.

In the Rollouts interface, navigate to 'Features > Create New Feature' and create a feature flag called 'hello_world'.

3. Install the Optimizely NodeJS SDK

The Optimizely NodeJS SDK allows you to setup feature toggles and run experiments from within your codebase.

Stop your running server with Ctrl+c and install the SDK from the command-line with:

npm install @optimizely/optimizely-sdk

In the root of your newly created application, add a file called optimizley.js and paste the following code:

const optimizelySDK = require('@optimizely/optimizely-sdk');

optimizelySDK.setLogLevel('info');
optimizelySDK.setLogger(optimizelySDK.logging.createLogger())

const optimizelyClientInstance = optimizelySDK.createInstance({
  sdkKey: '<Your_SDK_Key>',
  datafileOptions: {
    autoUpdate: true,
    updateInterval: 10000, // 10 seconds in milliseconds
  },
});

module.exports = optimizelyClientInstance;

Replace the placeholder of <Your_SDK_Key> with your SDK Key. To find your SDK Key, open up the Optimizely application and navigate to the far left 'Settings' > 'Environments' and copy the Production SDK Key value.

Nice! You've connected your newly created Optimizley account to your NodeJS application! You can now import this optimizely.js module anywhere in your NodeJS application that you want to evaluate feature flags.

4. Implement the Feature Flag

Require the optimizely.js module in your application where you want to implement your hello_world feature. In this tutorial, we'll import it at the top of the routes/index.js file of the Express application. Note the use of .. to go one directory level up from the routes/index.js file:

const optimizelyClientInstance = require('../optimizely.js');

Then use the isFeatureEnabled method from optimizelyClientInstance to evalaute the state of a feature flag:

const enabled = optimizelyClientInstance.isFeatureEnabled('hello_world', 'user123', {
  isVip: true,
  customerId: 123,
});

Note that isFeatureEnabled takes three parameters. The first is used to identify the feature you created in the Optimizely application. The next two are associated with visitors to your application:

  • userId: a string you provide that the Optimizely SDK uses for random percentage rollouts across your users. This can be any string that uniquely identifies users.
  • userAttributes: an object of key, value attributes used for targeting rollouts across your users. You will use the customerId attribute to target your feature to specific groups of users starting in step 6. isVip is just included as an example of the fact that you can pass in as many attributes as you want regarding the user.

Use the result of isFeatureEnabled to change the message on your Express application:

const title = enabled
  ? 'Feature Flag is On!
  : 'Feature flag is off :('

Your routes/index.js file should now look like:

var express = require('express');
var router = express.Router();
const optimizelyClientInstance = require('../optimizely.js');

/* GET home page. */
router.get('/', function(req, res, next) {
  const enabled = optimizelyClientInstance.isFeatureEnabled('hello_world', 'user123', {
    isVip: true,
    customerId: 123,
  });
  
  const title = enabled
    ? 'Feature Flag is On!'
    : 'Feature flag is off :('
  
  res.render('index', { title: title });
});

module.exports = router;

Congrats, you've now implemented your feature flag!

5. Turn the Feature Flag on!

If you save and re-run your application now, you'll notice that you did not get the feature. This is because the feature is not enabled, which means it's off for all visitors to your application.

To turn on the feature:

Log-in to the Optimizely project where you made your hello_world feature

  • Navigate to Features
  • Click on the 'hello_world' feature
  • Change to the 'Production' environment to match the SDK Key we used
  • Roll the feature out to ensure it is set to 100% for everyone
  • Click Save to save your changes

In less than 1 min, refreshing your NodeJS app should now show the feature toggled on and you should see "Feature Flag is On!". Congrats! You've implemented a feature flag in a NodeJS application. Hope you've enjoyed this tutorial!

6. Customize the Message with a Variable

Instead of turning on and off a hardcoded message, let's have a remote variable control the message of the feature.

In the Optimizely Application, navigate to your hello_world feature and click "Variable Keys & Types" in the left sidebar. Add a string variable named title that defaults to 'Default title'.

In code, after checking if the feature is enabled, use the getVariableString API to get the value in your codebase from Optimizely:

let title = 'Default title'
if (enabled) {
  title = optimizelyClientInstance.getFeatureVariableString('hello_world', 'title', 'user123', {
    isVip: true,
    customerId: 123,
  })
}

Notice the second parameter of the getFeatureVariableString method is the name of the variable you defined in Optimizely. Otherwise, the parameters are the same as the isFeatureEnabled method.

Now your routes/index.js file should now look like:

var express = require('express');
var router = express.Router();
const optimizelyClientInstance = require('../optimizely.js');

/* GET home page. */
router.get('/', function(req, res, next) {
  const enabled = optimizelyClientInstance.isFeatureEnabled('hello_world', 'user123', {
    isVip: true,
    customerId: 123,
  });
  
  let title = 'Default title'
  if (enabled) {
    title = optimizelyClientInstance.getFeatureVariableString('hello_world', 'title', 'user123', {
      isVip: true,
      customerId: 123,
    })
  }
  
  res.render('index', { title: title });
});

module.exports = router;

7. Target your feature

To target your feature based on the userAttributes you provided to the third parameter of isFeatureEnabled in step 3, you’ll have to create those userAttributes in the Optimizely Application.

Create the attribute ‘customerId’:

  1. Log-in to the Optimizely project where you made your hello_world feature
  2. Navigate to Audiences -> Attributes
  3. Click ‘Create New Attribute…’
  4. Name the attribute key ‘customerId’
  5. Click ‘Save Attribute’ to save your changes

Create an audience to use this new attribute:

  1. Navigate to Audiences
  2. Click ‘Create new audience’
  3. Name the Audience ‘[hello_world] Beta Users’
  4. Drag and Drop your customerId attribute into the Audience conditions
  5. Change the ‘has any value’ drop-down to “Number equals” with the value 123
  6. Click ‘Save Audience’

Add a rollout rule to our feature rollout for this new audience:

  1. Navigate to Features
  2. Click on your ‘hello_world’ feature
  3. Change the environment to “Production” to match the SDK Key we copied in step 1.
  4. Click the ‘Search and add audiences’ input box
  5. Add the ‘[hello_world] Beta Users’ audience
  6. Click ‘Save’ to save changes to the rollout

At this point your feature is only showing for customers with the customerId 123, which is what you provided to isFeatureEnabled method in step 4.

As a test to verify, you can change who is in the beta audience.

  1. Use the far left navigation to navigate to the Audiences dashboard
  2. Click the ‘[hello_world] Beta Users” Audience
  3. Change the customer id from 123 to 456
  4. Save your changes

In less than 1 min, refresh your browser showing the running NodeJS server application and watch as the feature will get turned off because you don’t meet the targeting conditions.

Congrats, you now know how to do targeted rollouts with your feature flags through Optimizely Rollouts!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment