Guide Getting Started With NodeJS Feature Flags · First, let’s create a new directory for our...
Transcript of Guide Getting Started With NodeJS Feature Flags · First, let’s create a new directory for our...
Getting Started With
NodeJS Feature Flags
Guide
2
INTRO
We’ve all done it at some point: thrown a conditional around a piece of code to
enable or disable it. When it comes to feature flags, this is about as simple as it
gets. But it’s far from really taking advantage of the power of feature flags (also
called feature toggles) to control functionality in our application.
This guide will walk you through implementing a feature flag in NodeJS using the
Rollout service. At the end of the article, you’ll have a dead simple application that
integrates with the feature flag service.
Ready? Good. Let’s get going!
3
STARTING WITH THE BASICS
First, let’s do some initial setup to make following this article easier. While we could
create an entire NodeJS Express web application, we’ll keep things simple and
create a basic Hello Rollout application.
First, let’s create a new directory for our project and generate a package.json file
using the npm init command.
Follow along with the prompts from the npm init command and just accept the
defaults. After all of that, you’ll have a new, bare-bones package.json file.
$ mkdir rollout-nodejs-demo && cd $_
rollout-nodejs-demo $ npm init
{
"name": "rollout-nodejs-demo",
"version": "1.0.0",
"description": "Example of using Rollout feature flags in NodeJS", "main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "..."
},
"author": "Casey Dunham",
"license": "MIT",
"bugs": {
"url": "..."
},
"homepage": "...",
"dependencies": {
}
}
4
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => { var message = '<h1>Hello Rollout!</h1>’;
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html'); res.end(message);
});
server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
rollout-nodejs-demo $ node app.js
Server running at http://127.0.0.1:3000/
Now, open up your favorite text editor, and let’s create our app.js file. The app.js
file will be our application’s main entry point.
Let’s run our application and make sure we have it all in working order.
Finally, open your browser and navigate to http://127.0.0.1:3000/, where you’ll see
our venerable greeting.
Alright, now that we’ve verified that everything is working, let’s get going and
create our first feature flag.
5
YOUR FIRST NODEJS FEATURE FLAG
Our application is functioning, but it’s not very exciting. Now, let’s say one day our
product manager decides we need to show our visitors a motivational message.
“No problem!” we say, and since we really like this product manager, their request
goes to the head of our task queue.
After a long meeting, the business decides what they want for a message. Don’t
ask; we weren’t invited to the meeting. Let’s go back to the app.js file and update
it to include the new message. Based on our experience, we know how these
requests can sometimes go, so we wrap the message in a conditional. This will
allow us to easily turn it off later if they decide they don’t want to show it anymore.
Open up your app.js, and let’s code this up before calling it a day.
Now run the application to see your new message in all its wonderfully obtuse
glory.
Congratulations! You’ve created your first feature flag in NodeJS. Now feel free to
head home since you’ve had such a productive day.
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const showMotivationalQuote = true;
const server = http.createServer((req, res) => { var message = '<h1>Hello Rollout!</h1>'; if (showMotivationalQuote) {
message += "<h3>The number zero. It's whatever you make of it.</h3>" }
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html'); res.end(message);
});
server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`);});
6
INTRODUCTION TO FEATURE FLAG
MANAGEMENT
Right now, you’re probably wondering about the point of what we just did. I don’t
blame you. Our feature flag is a bit lackluster. It doesn’t have any of the benefits
of what we can get out of a proper feature flag. Feature flags are intended to help
us release new functionality safely and without changing code. In order to achieve
those goals, we need to do a bit more.
We also haven’t solved any problems with our current code. In fact, we wrote some
code we didn’t have to. Feature flags can quickly get us into technical debt if we
aren’t careful. We’ll get to how to deal with that later in this article, so stick around.
7
GETTING THE CONFIGURATION OUT OF
CODE
Before moving on, let’s move the feature flag configuration outside of our code.
NodeJS will parse JSON files and bind them to a variable for us when using the
require statement. Create a config.json file and add the following contents to it:
Go back to your app.js file and update it to the following:
We’ve now moved the configuration outside of the code. However, if we want
to change this, we’ll still need to update the configuration file and redeploy
our application. We could handle the setting via an environment variable, but
that doesn’t solve the problem. It just moves it to another layer of indirection.
Implementing more flags in this manner will quickly make things complex and
error-prone. And you know there will only be more changes coming.
What we really want is to control the feature flag, and we want to do it without
touching or releasing new code. In other words, what we’re really looking for is a
way to centrally manage feature flags.
{
"showMotivationalQuote": true
}
const http = require('http');
const config = require('./config.json');
const hostname = '127.0.0.1';
const port = 3000;
const showMotivationalQuote = config.showMotivationalQuote;
const server = http.createServer((req, res) => { var message = '<h1>Hello Rollout!</h1>'; if (showMotivationalQuote) {
message += "<h3>The number zero. It's whatever you make of it.</h3>" }
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html'); res.end(message);
});
server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`);});
8
CENTRALLY MANAGING FEATURE FLAGS
At this point, you created a feature flag as a simple conditional and variable.
Then, you took it a step further to move the value into a configuration file. This
demonstrates the concept but doesn’t help us out much. We still need to redeploy
our application.
Companies such as Google and Facebook use feature flags to perform dark
launches and split testing. In order to reap the kinds of benefits these companies
enjoy by using feature flags, we need to do more than just use a hard-coded
variable.
To turn feature flags into the powerful tool that they are, we need to centrally
manage them. Luckily for us, you can do this as a service in NodeJS using Rollout.
9
GETTING STARTED
WITH ROLLOUT
Rollout will let you get started for free, so go ahead and create a Rollout account.
Then sign in and create a new app. Under “Installation Type,” select Javascript as
the language and NodeJS as the platform.
After clicking the “Start Installation” button, we’ll see a screen that describes how
to use the SDK from NodeJS. Let’s follow the instructions on the Rollout “Javascript
SDK” window.
We’ll go through each of these steps here, but refer to the NodeJS documentation
for more information.
Let’s install the Rox-node Rollout client package.
rollout-nodejs-demo $ npm i rox-node —save
10
This will update your NodeJS package.json file to include the Rox-node
dependency. After running the command, your package.json file should look like
the following:
Next, we need to open up the confg.json file and add our API key into it.
Finally, update your app.js file to read in the API key and add the call to Rox.setup().
{
"name": "rollout-nodejs-demo",
"version": "1.0.0",
"description": "Example of using Rollout feature flags in NodeJS", "main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "git+https://github.com/caseydunham/rollout-nodejs-demo.git" },
"author": "Casey Dunham",
"license": "ISC", "bugs": {
"url": "..."
},
"homepage": "...",
"dependencies": {
"rox-node": "^2.0.2"
}
}
const http = require('http');
const Rox = require("rox-node");
const config = require('./config.json');
const hostname = '127.0.0.1';
const port = 3000;
const showMotivationalQuote = config.showMotivationalQuote;
const server = http.createServer((req, res) => { var message = '<h1>Hello Rollout!</h1>'; if (showMotivationalQuote) {
message += "<h3>The number zero. It's whatever you make of it.</h3>" }
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html'); res.end(message);
});
server.listen(port, hostname, () => { Rox.setup(config.roxAPIKey); console.log(`Server running at http://${hostname}:${port}/`);});
{
"roxAPIKey": "5a68f9d5f807d908a1426405", "showMotivationalQuote": true
}
11
IMPLEMENTING FEATURE FLAGS
Once all that is done, go back to the Rollout administration screen. You’ll see that
it’s waiting for you to re-run your application. Do that, and the Rollout administration
screen will reward you with a happy success screen.
At this point, we’ve successfully integrated the Rollout service into our application.
We haven’t created any feature flags yet, though, so let’s get to work on that.
We’ll create a flags object that will act as a container for all of our feature flags. Go
back to your app.js file and add this object. We’ll also register this object with the
Rox client before the setup call.
const http = require('http');
const Rox = require("rox-node");
const config = require('./config.json');
const hostname = '127.0.0.1';
const port = 3000;
const showMotivationalQuote = config.showMotivationalQuote;
const roxFlags = {
showMotivationalQuote: new Rox.Flag()
};
const server = http.createServer((req, res) => { var message = '<h1>Hello Rollout!</h1>'; if (showMotivationalQuote) {
message += "<h3>The number zero. It's whatever you make of it.</h3>" }
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html'); res.end(message);
});
server.listen(port, hostname, () => { Rox.register("roxFlags", roxFlags);
Rox.setup(config.roxAPIKey); console.log(`Server running at http://${hostname}:${port}/`);});
12
Run the application and go back to the Rollout administration screen. You’ll see
that our feature flag was created and enabled on the server. Just like that, we’ve
created our first feature flag with Rollout. How cool is that?
In order to make this feature flag useful, we need to add it to an experiment.
Rollout manages feature flags through the concept of “Experiments.” Refer to the
Rollout documentation for more information on experiments. For now, click on the
“Production” link, as shown in the above screenshot. Next, click the “Experiments”
link from the dropdown menu.
Clicking on this will bring you to a screen with a “Create an Experiment” button. Go
ahead and click that and fill out the new experiment window.
13
Fill out the “New Experiment” window with sensible information. Then click the “Set
Audience” button and take a look at our next screen.
Now we can start doing some interesting things!
14
CONTROLLING THE FEATURE FLAG
Go back to your app.js file. We’ve set up the Rox client, but we’re still using the old
variable to manage our motivational message. We can check the status of a feature
flag through the isEnabled() method on the flag.
Update your app.js file to remove the hardcoded flag and use the Rollout feature
flag instead.
While we’re here, let’s update our config.json file to remove the
showMotivationalQuote setting.
Run your application and check it out in the browser. You’ll see that our
motivational message isn’t displaying. What broke? Well, nothing. It’s just that
Rollout defaults all new feature flags to false. This can be changed when creating
the flag, though.
const http = require('http');
const Rox = require("rox-node");
const config = require('./config.json');
const hostname = '127.0.0.1';
const port = 3000;
const roxFlags = {
showMotivationalQuote: new Rox.Flag()
};
const server = http.createServer((req, res) => { var message = '<h1>Hello Rollout!</h1>'; if (roxFlags.showMotivationalQuote.isEnabled()) {
message += "<h3>The number zero. It's whatever you make of it.</h3>" }
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html'); res.end(message);
});
server.listen(port, hostname, () => { Rox.register("roxFlags", roxFlags);
Rox.setup(config.roxAPIKey); console.log(`Server running at http://${hostname}:${port}/`);});
{
"roxAPIKey": "5a68f9d5f807d908a1426405" }
15
So let’s go back to the administration screen and update our feature flag by setting
it to true. Don’t forget to click the “Update Audience” button, as it doesn’t save the
changes automatically.
Now run your application. You’ll see the motivational message controlled through
the use of Rollout’s feature flag service.
Now run our application and delight in the non-determinism of whether or not we’ll
see our motivational message.
Congratulations! You’ve just implemented your first feature flag as a service.
Now you have the ability to change the behavior of your application—all without
touching configuration files or environment variables and without deploying new
code. We can now gradually roll out new features to our user base or perform split
testing between groups of users.
We can also change the percentage of what users will see our new message. Go
back to the “Experiments” screen with our feature flag and change it from true to
split. When set to split, the interface allows us to change the percentage set to true.
Here I set it to true for 30% of all users.
16
YOU TAKE IT FROM HERE
You can do even more with feature flags. Check out the Rollout documentation
for more information on additional options and customize-ability. And the
documentation also contains additional information on the management console.
Feature flags are a powerful tool. They allow you to respond quickly to market
trends and perform complicated A/B split testing—all without updating or
redeploying code. But you should keep it in mind that your feature flags need to be
managed, and that management must be simple, effective, and centralized.
ISSUES WITH FEATURE FLAGS
Feature flags are awesome. They enable us to run experiments in
production. However, there are some risks to using feature flags. First,
you can’t just use one feature flag. Implement one, and another will follow.
Go ahead and try to just give the marketing department a single one.
Lest we get ourselves into trouble with technical debt, feature flags need
management. They also need to have a retirement plan.
17
For more information:
visit https://rollout.io email us at [email protected]
Rollout is an advanced feature management
solution that gives engineering and product
teams feature control, post-deployment. It’s the
most effective way to roll out new features to the
right audience while protecting customers from
failure and improving KPI’s.