In the ideal world, we could test software easily. In the real world, things are quite messy.
Sometimes isn’t easy to test a new feature integrated with the whole system. Sometimes there’s a risk in releasing a feature, and we must release it in a controlled manner.
To help us with this, feature flags are a must.
What are Feature Flags?
Feature Flags, also known as Feature Switches, Feature Toggles and so on, are a simple mechanism to remotely configure an application.
Let’s pretend that you need to release the feature X in production. You merge your feature branch into the main branch, and start the deploy process. Suddenly, some minutes after releasing your feature, you figure out that you also released a new bug that is impacting in the purchasing conversion.
Now you panic and try to revert your changes as fast as possible, but if the feature depends on front-end code, you will have to deal with clients using cached versions if your caching expiration mechanism isn’t configured right. Until then, you will need to deal with your manager (or even C-level people) calling or messaging you on Slack.
A controlled rollout comes to the rescue.
Let’s pretend a new situation, where instead of releasing your new feature for all users at once, you now configure a feature flag in your feature branch to only enable the new feature for a set of users. You then merge your feature branch into the main branch and proceed to deploy in production.
For all users, nothing happened. But for selected users — and this selection could include only you, or only your team, the new deploy released the new feature. You then test in production and verifies that the feature contains a bug. Instead of panicking, you create a new Jira issue and start working on the solution.
Do you want to be part of which story? The one that you messed up the application or the one that you release a new feature securely, without downtime and without making customers mad?
How to use Feature Flags?
This depends on the project tech stack. Currently, I’m using Firebase remote configuration as a feature flag platform. Our team creates a new feature flag when we need to release a new feature that we want to rollout it securely. Or when we need to test in production, or even when we have a feature so big to implement that we must deliver parts of it and incrementally release more parts of that feature.
For this latest use case, having feature flags are pretty useful. You can split the feature into many pieces and merge them as soon as they are developed, tested, reviewed and so on. No more gigantic merges, but instead many small incremental merges.
To give you a more concrete example, let’s pretend that we are implementing a new feature into the checkout page that displays other products that have similarities with the products present in the user’s current cart.
For that, we could create a feature called view_similar_products_at_checkout
. I like to have a dedicated React custom hook to validate the feature flag status. Let’s create the feature flag and give it the value of an array containing only my e-mail, for example ["my-email@domain.com"]
.
When the application access this feature flag, it will receive the array containing the user emails with access to this new feature.
To ease the code reading, I’ll create a hook called useFeatureViewSimilarProductsAtCheckout
that returns a boolean value if the authenticated user has access to this feature:
function useFeatureViewSimilarProductsAtCheckout() {
let currentUser = useCurrentUser()
let featureFlags = useFeatureFlags()
let value = featureFlags.get("view_similar_products_at_checkout")
if (!value) return false
if (value === "*") return true
return value.includes(currentUser.email)
}
In this example, useCurrentUser
returns the current logged user object, where we can access the email through email
property. useFeatureFlags
returns an object where we can query for a feature flag value, in the line 4, we get the value of view_similar_products_at_checkout
.
Then we consider three cases: one that the feature flag doesn’t exist. By default, we will let the feature disabled and return false
. When the feature flag value is the string "*"
we know that the feature is enabled for any user, then we return true
. Otherwise, the feature value is the array of emails, and we just need to check if the email of the current user is included in the list of enabled users on this feature.
This code is pretty straightforward and quite a powerful abstraction. We now just need to call this React hook and verify if we either show the new products section at the checkout or not.
There are plenty of ways of releasing code in production in a safe manner. Feature flags are one of them. It is easy to adopt, and the outcome is quite generous. Also,there are many ways to implement it. The example that I gave depends doesn’t depend on any platform, and this is intentional. You can use many ways to manage feature flags and their values.
I’ve mentioned using Firebase remote configuration, but you can implement mechanism that depends on Redis to store feature flags, or even a database table.
By adopting feature flags I’m certain that your development process will become way better, and you will be happier at your job delivering more features and only causing good impact in production.