Playing with Flipper
I want to have a Feature Flag system in my Ruby on Rails apps, where a production system can have features changed without another code deploy. Some use a user interface to change values, some give an API to roll your own, some expect you to have console access.
In this article, I play around with Flipper, a Ruby on Rails gem that provides a way to toggle features on an off.
I want to understand how Flipper works and answer these questions:
- Can I flip parts of code on and off?
- Is there a user interface to do this?
- Is the system so complicated that only developers can access?
- Is the system easy for developers to incorporate into their work flow?
These are probably my big concerns in incorporating feature flags in systems I work with.
Why Flipper?
A team member recommended Flipper as they used it previously. I also like the fact it is recently updated and there is a dedicated user interface component.
I looked at their test suite, this is impressive. The Flipper team takes their code quality seriously.
Play
As much as I want to “TDD” everything, this is not one of those times. Doing test driven development requires one to know how to get to the goal. In this case, I kind of do not, I have an end goal in mind, but not how to get there.
So, I want to just play around with Flipper, see how it feels, does it fit my needs, how different is my mindset vs. the frameworks?
At the same time, I will make this into structured play, so others can gain the benefit of my “play”.
All code can be found here
Requirements
- System that can run Rails 5.1. I am using Ubuntu 16.04
- Or start with this vagrant setup
At the time of writing, I tried Flipper with Rails 5.2.2 but ran into issues. Downgrading to Rails 5.1 alleviated problems I had.
Get Rails Setup
If you have Ruby on Rails 5.1 installed, skip to the next section.
vagrant@ubuntu-xenial:/vagrant$ gem install rails -v 5.1.6.1
Successfully installed rails-5.1.6.1
Parsing documentation for rails-5.1.6.1
Installing ri documentation for rails-5.1.6.1
Done installing documentation for rails after 0 seconds
1 gem installed
# Create new Rails application
vagrant@ubuntu-xenial:/vagrant$ rails new play_flipper
create
create README.md
create Rakefile
create .ruby-version
...
Bundle complete! 18 Gemfile dependencies, 79 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
run bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted
Tip: If the system has multiple versions of Rails installed, to
use different version of rails: rails _version_ optiosn
(i.e. rails _5.1.6.1_ --version )
Modify the Gemfile
In the Gemfile, perform the following:
source 'https://rubygems.org'
gem 'rails', '~> 5.1.6', '>= 5.1.6.1'
gem 'sqlite3', '~> 1.3'
gem 'flipper'
gem 'flipper-ui'
Run $ bundle
to install the additional gems
vagrant@ubuntu-xenial:/vagrant/play_flipper$ bundle
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies....
Using rake 12.3.2
...
Using rspec-rails 3.8.2
Using sqlite3 1.4.0
Bundle complete! 7 Gemfile dependencies, 52 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Configure Flipper to Start up
Create an initializer file: config/initializers/flipper.rb
to
configure Flipper on start up:
require 'flipper'
Flipper.configure do |config|
config.default do
adapter = Flipper::Adapters::Memory.new
Flipper.new(adapter)
end
end
Make Flipper UI Accessible
To take advantage of the Flipper dashboard, in config/routes.rb
,
change the contents to:
Rails.application.routes.draw do
mount Flipper::UI.app(Flipper) => '/flipper'
end
This will show Flipper’s dashboard when loading URL: http://localhost:3000/flipper.
Start Your Rails
With all the pieces for Flipper in place: initializer and routes entry, let’s start Rails:
vagrant@ubuntu-xenial:/vagrant/play_flipper2$ bin/rails s
=> Booting Puma
=> Rails 5.1.6.1 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.3-p105), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
and open a web browser to: http://localhost:3000/flipper to see:
Yup, gotta love Blank Space! ;-)
New Feature
There are two ways to add a new feature to the Flipper user interface list: directly through the user interface and through code.
User Interface
To include a new feature, just hit: “Add Feature” and type one out:
Through Code
In playing around, I seeded the feature list in the Flipper user
interface through the config/initializer/flipper.rb
file by adding
new features using the following code:
Flipper[:new_feature_enabled].enable
Flipper[:new_feature_disabled].enable
Flipper[:new_feature_disabled].disable
Loading the Flipper user interface now lists:
Incorporating with Code
To use the feature flags registered with Flipper in code, I’ll try it
out with a basic endpoint: /version
:
vagrant@ubuntu-xenial:/vagrant$ rails generate controller version
...
Add the appropriate entry in the config/routes
file:
Rails.application.routes.draw do
mount Flipper::UI.app(Flipper) => '/flipper'
get '/version', to: 'version#index'
end
and edit the app/controllers/version
file to have:
class VersionController < ApplicationController
def index
version = if Flipper[:beta].enabled?
'beta'
else
'current'
end
render json: { version: version }
end
end
To test out, let’s make a curl request:
vagrant@ubuntu-xenial:/vagrant$ curl localhost:3000/version
{ "version": "current" }
From the Flipper user interface, register the beta
feature flag and
set it to enable perform the same request again:
vagrant@ubuntu-xenial:/vagrant$ curl localhost:3000/version
{ "version": "beta" }
Tada~! So magical.
Conclusion
After playing around with Flipper and it’s user interface, I have found out how to:
- configure a new Ruby on Rails application with Flipper
- add new feature flags through the UI
- add new feature flags in code
This solves the initial questions I had:
- Can I flip parts of code on and off? Yes, by using
Flipper[:flag].enabled?
- Is there a user interface? Yes, by going to
http://localhost:3000/flipper
- Is the system so complicated that only developers can access? No, through the Flipper user interface, one can see registered feature flags and add their own.
- Is the system easy for developers to incoporate into their work flow? Requires research.
I spent most of this article setting up Flipper and answering the first set of questions, I would like time to explore this and other features of Flipper in another article.