A common interface to interact with many feature flag providers.
ThisFeature can be used to more easily migrate from one feature flag service to another
If your code uses ThisFeature, then you can just swap out the vendor adapter without needing to do a bunch of find-and-replace in your codebase from one vendor's class/method signature to the another's.
Add ThisFeature to your Gemfile
:
# Gemfile
gem 'this_feature'
Then from your Rails app's root directory:
bundle install
# config/initializers/this_feature.rb
require 'this_feature'
require 'this_feature/adapters/memory'
ThisFeature.configure do |config|
adapter = ThisFeature::Adapters::Memory.new
config.adapters = [adapter]
config.default_adapter = adapter
end
NOTE: When searching for the presence of a flag, adapters are queried in order. The default adapter is the fallback adapter used when a flag isn't present in any of the adapters.
ThisFeature.flag('flag_name').on? # is the flag is turned on?
ThisFeature.flag('flag_name').off? # is the flag is turned off?
ThisFeature.flag('flag_name').control? # is the adapter using the control?
ThisFeature.default_adapter # access the default adapter directly if needed
You can also pass a context
to the flag, many feature flagging systems support this.
ThisFeature.flag('flag_name', context: current_user).on?
In case context
is not sufficient, you can also pass a data
hash.
ThisFeature.flag('flag_name', context: context, data: { org_id: 1 }).on?
- If your flag has context-specific rules (e.g. on for some orgs, off for others), make sure that the code does a context-specific check.
ThisFeature.flag("flag_name").on?
may return true, whileThisFeature.flag("flag_name", context: Org.first).on?
would return false. - Related to the previous bullet point, if you are checking whether a flag is "globally enabled" (and thus may be removed from the codebase), do not just use
ThisFeature.flag("flag_name").on?
, it won't tell you the whole story. Go to the vendor console and check whether there are context-specific rules enabled.
These adapters do behave slightly differently, so make sure to read the following docs:
- Flipper adapter
- Split.io adapter
- Memory adapter - designed for use in tests
We'd like to add more adapters for more vendors. If you're using a different backend and write your own adapter, please submit a pull request to upstream that adaptor into this repo.
- Launch Darkly
- YAML files
- ...
The tests are a good reflection of the current development state. You can run the tests with these commands in your Terminal:
bundle install && bundle exec rspec
To write a new adapter, check the Guide.
If you are working at Hover, see this confluence doc
ThisFeature is released under the MIT License.