Railsでの機能フラグ導入(gem flipperを使う)

Railsでの機能フラグ導入(gem flipperを使う)の説明画像

満を持してリリースはやめにしたい

Railsアプリで新機能をリリースするとき、こんな不安を感じたことはないでしょうか。

  • 本番にデプロイした瞬間、全ユーザーに影響が出てしまう
  • 一部の顧客だけに先行リリースしたい
  • 問題が起きたらすぐに機能を止めたい

こうした課題を解決するのが Feature Flag(機能フラグ) です。
そして、そのための Ruby gem として非常によく設計されているのが flipper です。

この記事では flipper の導入方法や使い方のイメージなどについて記します。

Feature Flagとは何か

Feature Flag(機能フラグ)とは、

コードは本番にあるが、機能としてはまだ有効化しない

という状態を作る仕組みです。

つまり、

デプロイ = コードを本番に置く
リリース = ユーザーに見せる

この2つを分離する技術です。

これがないと、Railsアプリは

  • デプロイ = 即ユーザー影響
  • 問題があればロールバック

という非常にリスクの高い運用になります。
Feature Flagを使えば、

  • 社内だけで有効化
  • 特定の会社だけでON
  • 少しずつ対象を広げる(カナリアリリース)

といった運用が可能になります。

flipper の思想

flipper は README でこう定義されています。

A simple, flexible feature flagging solution for Ruby.

しかし実際の設計を見ると、もう少し踏み込んだ思想があります。

flipper は
「Feature Flag の判断を、外部サービスに丸投げせず、アプリケーションのドメイン側で管理する」
という設計をしています。

保存先は Redis や DB などアダプタで差し替えられますが、
「誰にこの機能を見せるのか」という判断ロジックは、
あくまで Rails アプリの中にあります。

ActiveRecord アダプタを使えば、その判断はそのまま DB に保存されます。
これはつまり、

機能フラグは、ただの設定ではなく、業務ルールとして扱える

という状態を Rails の中に作れる、ということです。

Railsのモデルやドメインと一緒に
「この会社にはこの機能を出す」というルールを管理できる。
そこが flipper の大きな特徴です。

flipper を ActiveRecord で導入する

今回は flipper の中でも、Railsと最も相性が良い
ActiveRecordアダプタを使います。

Gemfile

gem 'flipper'
gem 'flipper-active_record'
bundle install

マイグレーション

rails generate flipper:active_record
rails db:migrate

これで次のテーブルが作られます。

  • flipper_features
  • flipper_gates

この時点で、Feature Flagは
RailsのDBに保存されるデータ になっています。

flipperのDB構造

flipper_features

id key
1 new_ui
2 beta_export

→ 機能フラグの一覧です。

flipper_gates

feature_key key value
new_ui boolean true
new_ui actor Company;42
new_ui group admins

ここが flipper の本体です。

flipper は Feature Flag を「3種類のゲート」で管理します。

ゲート 意味
boolean 全体ON / OFF
actor 特定のユーザー・会社
group 管理者・βユーザーなど

単なる true / false ではなく、
誰に対して有効なのか まで DB に保存されます。

単純なON / OFF

Flipper.enable(:new_ui)
Flipper.disable(:new_ui)

このとき、DBにはこう保存されます。

feature_key key value
new_ui boolean true

「この機能は全員に対してON」という意味です。

特定の会社だけONにする(カナリアリリース)

ここが flipper の真価です。

company = Company.find(42)
Flipper.enable_actor(:new_ui, company)

このとき DB にはこう保存されます。

feature_key key value
new_ui actor Company;42

flipper は ActiveRecord オブジェクトを

"Company;42"

という ドメイン識別子 に変換して保存します。

User ID やメールアドレスではなく、
Railsのモデルそのもの をキーにしてフラグを管理する。
これが flipper の思想です。

なぜDBで持つ設計が強いのか

Redis や外部サービスと違い、ActiveRecord を使うと

  • マイグレーションで変更を管理できる
  • バックアップ・復旧の対象になる
  • 「誰に何をONにしたか」が業務データとして残る

つまり Feature Flag が

設定ファイルではなく、契約データになる

という状態になります。

これは BtoB の Rails アプリでは特に重要です。

flipperで実現するカナリアリリース

Flipper.enable(:new_ui) # 社内
Flipper.enable_actor(:new_ui, Company.find(5))
Flipper.enable_actor(:new_ui, Company.find(8))

これだけで、

  • まず社内
  • 次に数社
  • 問題なければ全体

というリリースが 再デプロイなし で実現できます。

問題が起きたら、DBからフラグを消すだけです。

flipperとは何か

flipper は単なる if 文のラッパーではありません。

flipper が提供しているのは、

「この機能を、どのユーザー・どの会社に出すか」
という判断を、コードではなくデータとして管理できる仕組み

です。

ActiveRecord アダプタを使えば、

  • この会社には new_ui をON
  • あの会社にはまだOFF
  • 管理者だけON

といったリリース状態が、そのまま Rails の DB に残ります。

つまり flipper は、

機能の公開範囲を、デプロイとは切り離してコントロールできるようにするgem

です。

段階リリースや顧客ごとの出し分けが必要な Rails アプリでは、
運用と設計の両方をシンプルにしてくれる、かなり実戦的な選択肢だと感じています。

この記事をシェア