Red Green Repeat Adventures of a Spec Driven Junkie

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.

Dolphin 1

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:

Flipper Initial Screen

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:

Flipper Add Feature in UI

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:

Flipper List Preset Flags

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.