-
Notifications
You must be signed in to change notification settings - Fork 10
Feature Flags
Feature flagging is a technique for enabling or disabling features within our code. Because we have daily releases to production, we need a way to be able to work on large features iteratively without delaying a release or using large PRs / feature branches. The solution is to hide our features behind a conditional based on the value of a feature flag. By doing this, we can iteratively work on a large feature via multiple PRs without impacting the existing flow of our UI until it's time to ship the feature to production.
All feature flag utilities are stored within the featureFlag.ts module. There are 5 key aspects of the feature flag module:
- Feature flag environment
- Feature flag key
- Feature flag map
-
getFeatureFlag()
util function -
useFeatureFlag()
React hook
There are 4 environment values that correspond to our deployment environments. They're defined as a string literal type:
export type FeatureFlagEnvironment = 'local' | 'dev' | 'staging' | 'prod'
The environment strings are used for determining which environment a particular feature flag is enabled for.
The feature flag key is a string literal type that defines all possible keys for our feature flag. This is primarily used to strictly type the keys that can be used when using the feature flag util functions.
export type FeatureFlagKey =
| 'someFeature1'
| 'someFeature2'
| 'someFeature3'
| 'someFeature4'
The feature flag map is a mapping of feature flags to a list of environments the feature flag is enabled for:
export const FEATURE_FLAGS: Record<FeatureFlagKey, FeatureFlagEnvironment[]> = {
someFeature1: ['local', 'dev'],
someFeature2: ['local', 'dev'],
someFeature3: ['local', 'dev', 'staging'],
someFeature4: ['local', 'dev', 'staging', 'prod'],
}
The getFeatureFlag()
util function is used for getting the value of the feature flag. It's a generic function that takes in the environment
and URL search params as input, and returns the true
or false
depending on if the flag is enabled for the environment input or if a URL search param override is provided. This function is primarily useful in non-React contexts (i.e. on the server side).
The useFeatureFlag()
function is a React hook that serves as a convenient interface for using the getFeatureFlag()
function without needing to pass in the environment or URL search params. This function should be used over the getFeatureFlag()
function in most use cases when working in React.
When adding a new feature flag, all you need to do is:
- Add the feature flag key
- Add the
local
anddev
environments to the feature flag map - Conditionally render your feature code based on the feature flag value
// Add new feature flag key
export type FeatureFlagKey =
| 'someFeature1'
| 'someFeature2'
| 'someFeature3'
| 'someFeature4'
+ | 'newFeature
// Add to feature flag map
export const FEATURE_FLAGS: Record<FeatureFlagKey, FeatureFlagEnvironment[]> = {
someFeature1: ['local', 'dev'],
someFeature2: ['local', 'dev'],
someFeature3: ['local', 'dev', 'staging'],
someFeature4: ['local', 'dev', 'staging', 'prod'],
+ newFeature: ['local', 'dev'],
}
import { useFeatureFlag } from 'app/utils/featureFlag'
function Example() {
const isNewFeatureEnabled = useFeatureFlag('newFeature')
if (isNewFeatureEnabled) {
return <NewCode />
}
return <OldCode />
}
When a feature is ready, you can release it to another environment by adding the environment key to the feature flag map and wait for the next deployment.
export const FEATURE_FLAGS: Record<FeatureFlagKey, FeatureFlagEnvironment[]> = {
someFeature1: ['local', 'dev'],
someFeature2: ['local', 'dev'],
someFeature3: ['local', 'dev', 'staging'],
someFeature4: ['local', 'dev', 'staging', 'prod'],
- newFeature: ['local', 'dev'],
+ newFeature: ['local', 'dev', 'staging', 'prod'],
}
Feature flags can be overridden by specifying a special query parameter to enable or disable a particular feature. The --enable-feature
parameter will enable a feature, and conversely the --disable-feature
parameter will disable a feature.
For example, if the new feature is on the browse datasets page, you could enable the feature by visiting:
https://cryoetdataportal.czscience.com/browse-data/datasets?enable-feature=newFeature