Flip Fab [DEPRECATED]
Status: DEPRECATED
Please use Amplitude Experiment instead for AB testing in Chopin! More here.
Feature flipping... Made FaBuLoUs!
A gem providing persistent (via cookie store) feature flipping to Rack applications.
This allows you to...
- Define features that can be used to modify the behaviour of an application
- Persist the features' states in a user's cookie so that they see a consistent feature set for all applications in a domain
- Define your own custom persistence adapters to persist features in your own data store
Usage
Add the following to your Gemfile
gem 'flip_fab'
Rails
The helper will be included in ActionController::Base
as a view helper method when the gem is loaded.
Sinatra
Add the following to Sinatra::Base
require 'flip_fab'
helpers FlipFab::Helper
Defining a feature
For Rails, this could go in config/initializers/flip_fab.rb
FlipFab.define_feature(:name_of_feature) # default state: :disabled
FlipFab.define_feature(:name_of_other_feature, { default: :enabled }) # default state: :enabled
Enabling/disabling a feature for a user
Within the context of a controller
features[:name_of_feature].enable # Enable the feature for the user
features[:name_of_feature].enabled? # => true
features[:name_of_feature].disable # Disable the feature for the user
features[:name_of_feature].disabled? # => true
- If the feature is not defined,
features[:name_of_feature]
will raise an error - The enabled/disabled feature will be stored in the user's cookie
Outside of a controller
Outside of a controller, features cannot be enabled/disabled for individual users.
From URL params
You can explicitely request a feature to be enabled or disabled in your session by passing the desired state of a feature in the parameters of your request:
http://localhost:3000?name_of_feature=enabled&name_of_other_feature=disabled
- The features' states specified in the URL will take precendence over those specified in the controller
- The enabled/disabled features will be stored in the user's cookie
- Smoke tests could enable or disable features using this mechanism
Note: This will enable users of a production system to show/hide features in their session. While this allows automated tests to be run against staging/production environment against a particular set of features, this will allow users to 'customize' their experience, so consider what types of features a user could be switching on and off i.e. authentication, security, etc.
Checking if a feature is enabled
From within a controller or view
# With the feature having been enabled for the user:
features[:name_of_feature].enable # Enable the feature for the user
features[:name_of_feature].enabled? # => true
features[:name_of_feature].disabled? # => false
Outside of a controller/view
# With the feature defined like this:
FlipFab.define_feature(:name_of_feature) # default state: :disabled
FlipFab.features[:name_of_feature].enabled? # => false
FlipFab.features[:name_of_feature].disabled? # => true
Precedence of feature lookup
- URL parameter
- Code (e.g.
features[:name_of_feature].enable
) - Cookie
- Default
Cookie persistence
Out of the box, the features a user receives can be persisted in their cookie. The cookie will have the following parameters:
Parameter | Value |
---|---|
Name | flip_fab.[name of feature] |
Value | `enabled |
Path | / |
Expires | One year from now |
Domain | The top-level domain |
To persist the features in a user's cookie, do any of the following operations
features[:name_of_feature].enable # Enable the feature for the user
features[:name_of_feature].disable # Disable the feature for the user
features[:name_of_feature].persist # Persist the feature for the user
Defining a custom persistence adapter
- Create a class that extends the
FlipFab::Persistence
class
class ExamplePersistence < FlipFab::Persistence
def initialize feature_name, context
super
end
def read
# lookup the state of the feature
end
def write state
# write the state of the feature
end
end
-
Implement the
read
andwrite
operations. The following variables will be available fromFlipFab::Persistence
-
feature_name
- the name of the feature to be read/written -
context
- the controller context (whatever class has includedFlipFab::Helper
) -
Include your persistence class when defining the feature
FlipFab.define_feature(:name_of_other_feature, { persistence_adapters: [ExamplePersistence] })
Note that you can define multiple custom adapters that will be read in precedence of the order specified
Example app
There is an example app that demonstrates the use of FlipFlab in example/rails_app
. The app has a feature called :justin_beaver
that allows you to flip the image on the page between a beaver and a 'justin beaver'.
Perform the following to try the example:
- Go into the app:
cd example/rails_app
- Install the gems:
bundle install
- Run the migrations:
bundle exec rake db:migrate
- Start rails:
bundle exec rails s
- View the page with the feature disabled:
open 'http://localhost:3000/beavers?justin_beaver=disabled'
- View the page with the feature enabled:
open 'http://localhost:3000/beavers?justin_beaver=enabled'
Contributing
- Make your changes in a branch
- Update the version using semantic versioning in
lib/flip_fab/version.rb
- Once signed off, merge
- The gem will automatically be pushed to gemstash