Flagon - An Agnostic Feature Flag Gem
Last month the Sittercity tech team released Flagon, a simple gem that you can use to quickly set up feature flags in your project without worrying about how you might need to store these flags in different environments.
Feature flags you say…
Okay, let’s make sure we’re all reading the same page.
Imagine you are developing a particularly risky piece of code. Your client has asked for the ability to turn the risky feature off at the snap of a finger if anything goes wrong in the wild, and you need a way to flick that switch.
This is a common scenario that many software engineers have encountered before and many more will encounter in the future, these switches we use to turn features on and off are often called feature flags.
Okay, but there are other feature flag gems. What’s so special about Flagon?
Before developing a new gem, it would be silly not to check if the problem had already been solved by some other nice person. However, upon looking for something to fill our gap, we discovered that there were not a lot of choices out there that deal with this problem in a flexible way. Most are tied to active record or another single type of storage, and while this may be convenient because you’re already in the database most of the time, it doesn’t comply with the ideals of the 12 Factor App by storing settings in environment variables, and lets face it, for development and testing something a lot simpler could be used to define flags that doesn’t involve database migrations, like a hash.
Having said that, I’m not going to waggle my finger at you and tell you you’re doing it wrong. If you want to use the database for feature flags in some cases, so be it! You can. Flagon allows any storage mechanism if you care to extend it.
Using Flagon, the simplest example
In it’s simplest form, Flagon can be set up to use environment variables in one line:
Flagon expects environment variables to be set to “on”. If they are not “on” then they are considered off. So to set up your first flag you could set an environment variable like so:
Then, you would check the flag in your project by calling:
Alternative ways of defining flags
You might not want to use environment variables all the time, maybe you want something even simpler, like a hash? You can do this by initializing a hash loader and passing it into the init method of Flagon:
Other than that change (and not needing to set environment variables), you use Flagon in exactly the same way as before. To keep things consistent with the environment variables, we stuck with “on” to define an enabled flag.
In addition to the hash loader, Flagon also provides the file loader which will read from a yaml file:
The yaml file is simple too:
Extending Flagon
If environment variables, hashes and yaml aren’t your thing you can create your own loaders too. You just need to implement the loader interface on a custom object and pass it in instead of one of the provided loaders. Here’s the loader interface:
Flagon will call those two methods to work out whether a flag is on or off and your application can be blissfully ignorant about how or where the flags are defined in development, test or production.
For example, if you created a new rails project and an active record model with two attributes “name” and “value”, you could implement the two interface methods like so:
Then you could simply pass it into Flagon to have all your flags load from your database rather than environment variables:
Telling, rather than asking
If you’re the type of person that likes to tell your programs what to do rather than ask them, you can use this smashing alternative syntax:
It’s basically the same thing… but you might enjoy the small power rush it gives you.
Crossing your Ts and dotting your Is
If you haven’t set a flag, it will be considered to be off. There’s nothing wrong with a flag being off of course, but you may want to make sure that the flag is in fact, supposed to be off. Flagon provides a method that can be used to check if flags have been set as expected.
If either flag hasn’t been set, ensure_flags_exist
will raise a Flagon::Inspector::FlagMissing
exception. We like to call it immediately after initializing Flagon so that we know about possible problems as early as possible.
Anything else?
Maybe! This post is unlikely to change over time, but we will certainly keep the readme of the project up to date with changes and improvements so visit the Flagon project page for the latest details on the gem.