フィーチャーフラグとは 基礎から実装まで

要約

フィーチャーフラグは、コードを再デプロイせずにランタイムで機能をオン・オフ切り替える条件分岐です。トランク・ベース開発や段階的なロールアウトを可能にしますが、時間とともに技術的負債になります。リリース・実験・Ops・パーミッションの4タイプと、200個以上のフラグを保つチームのクリーンアップ戦略を解説します。

Engineer desk with a row of physical toggle switches beside a laptop

フィーチャーフラグは、デプロイを伴わずにランタイムで機能のオン・オフを判定する条件分岐です。これが基本的な考え方です。実践でのフィーチャーフラグとは何か?設定ファイル、データベース行、またはフラグサービスから答えが得られるif文です。コンセプトは単純です。しかし、リポジトリに200個も存在すると、話は複雑になり、このガイドはまさにそこに焦点を当てています。

フィーチャーフラグはコードでどのように見えるか

最小限でも実用的なバージョンは次の通りです。

if (flags.isEnabled("new-checkout", { userId })) {
  return renderNewCheckout();
}
return renderOldCheckout();

両方のコードパスは同じビルドに含まれます。フラグ値は再デプロイなしで変更できる場所にあります。環境変数、JSONファイル、テーブル、またはホストされたサービスです。値を変更すると、次の評価時に動作が変わります。

この分離がポイントです。デプロイメントはサーバーにコードを配置することです。リリースはユーザーがそれを見ることです。フラグはこの2つのイベントを分割するため、mainにマージしても「全員が今これを取得する」という意味ではなくなります。

Hand flipping a single toggle switch with a green indicator light

なぜチームはフィーチャーフラグを使用するのか

実際のチーム(エンジニア5~50人)では、同じ3つの理由が何度も浮かび上がります。

これらのいずれもベンダーを必要としません。フラグは設定テーブルのブール値になります。パーセンテージロールアウト、監査証跡、またはエンジニア以外が物を切り替える必要があるまで、プラットフォームをスキップしてください。

フィーチャーフラグの4つのタイプ

Pete Hodgsonの広く引用されているMartin Fowlerのサイトのフィーチャートグル記事では、フラグはそれがどのくらい存続し、判定がどのくらい頻繁に変わるかによって分類されています。カテゴリーは今でも最も明確なメンタルモデルです。

有効期限の欄が最も重要です。リリースフラグがそのリリースより長く存続している場合、それはまだ見つかっていないバグです。パーミッションフラグがクリーンアップスプリントで削除される場合、それはまだ起こっていない停止です。

フラグを作成する際に、タイプと名前を付けて、ラベルを付けてください。6ヶ月後、誰も「new-nav-v2」がどのカテゴリーのものか覚えていません。

Team planning grid of sticky notes grouped by category

ユーザーに害を及ぼさずにフラグをロールアウトするにはどうしたらよいか

つまらないシーケンスが最適です。

  1. フラグがオフの状態でコードを出荷します。何も変わらなかったことを確認します。

  2. 本番環境の自分のチームに対して有効にします。1日それを使用します。

  3. ユーザーの1%~5%に対して有効にします。ユーザーIDで粘着性のあるもので、セッション中に誰も変種間をフリップしません。

  4. エラー率、レイテンシ、および1つのビジネスメトリックを監視します。ダッシュボードをじっと見つめながらではなく、開始する前に閾値を決めてください。

  5. 100%にランプアップし、定義された期間待ってから、フラグを削除します。

ステップ5は、チームがスキップするステップです。そこにコストがかかる理由については後で説明します。

評価に関する実用的な注記:フラグ読み込みを安い失敗セーフなものにします。フラグサービスがダウンしている場合、コードにデフォルトが必要です。フラグあたりのデフォルトを選択してください。キルスイッチは「安全」に失敗するはずですが、新しい機能は「オフ」に失敗するはずです。

フィーチャーフラグが技術的負債になるのはなぜか

すべてのフラグはコードのフォークです。2つのフラグは4つの可能なパスを作ります。10個のフラグは1,024個を作ります。そして、あなたはそれらのほんの一握りをテストしたと思っています。GrowthBookのフラグ負債の技術ガイドは、約75%のトグルコンポーネントが導入後最大49週間までコードベースに残っていたことを示す研究を引用しています。ほとんどのデベロッパーが削除予定だと述べていたにもかかわらずです。

同じFowler記事でHodgsonは適切に述べています。賢明なチームはトグルをキャリングコスト付きの在庫として扱い、その在庫を低く保つために機能します。

古典的なホラーストーリーは2012年のKnight Capitalです。廃止されたフィーチャーのフラグが、古いコードがまだ1つのサーバーに存在している間に新しい動作のために再利用されました。そのミスマッチは約1時間以内に約4億6000万ドルの損失に貢献しました。あなたの古いフラグはそれをしないでしょう。より静かなことをします。誰も存在していることを知らない分岐を壊すリファクタリング、または2つのチェックアウトパスのどちらが本当かを理解するために午後を費やす新しい雇用。

Dusty shelf of forgotten boxes and old switches

既存のコードベースにおいて、すべてのフラグをどのように見つけるか

これは、ベンダードキュメントがスキップする質問であり、ほとんどのチームが立ち往生する場所です。フラグダッシュボードは、何が構成されているかを教えてくれます。それぞれのフラグがコードのどこで読み込まれているか、または「オフ」のフラグの背後にあるコードパスがまだアクセス可能であるかどうかは教えてくれません。

安い手法で始めます。

# ラッパーを介して読み込まれるすべてのリテラルフラグキー
rg -n 'isEnabled\("' src/ | sort

# 定義されているが参照されていないフラグ
comm -23 <(jq -r 'keys[]' flags.json | sort) \
         <(rg -o 'isEnabled\("([^"]+)"' -r '$1' src/ | sort -u)

これは急速に分解されます。文字列連結から構築されたフラグキーはgrepに表示されません。ヘルパー機能を通じて渡されたフラグは、呼び出しサイトを隠します。モノレポと複数レポ設定は問題を乗算します。同じキーは3つのサービスによって読み込まれる可能性があります。

ここで、ツールでコードを読むことが役立ちます。リポジトリを理解するコード検索ツールは、「new-checkoutが評価される場所と、結果が何に依存するか」という質問に1回のクエリで答えることができます。午後の代わりにgrepします。CursorとGitHub Copilotは1つのリポ内で合理的に対応します。複数のリポにまたがって、すべてのリポにまたがるインデックスが必要です。これはcodebasechatが構築した場合です。

理にかなったフラグクリーンアッププロセスはどのように見えるか

削除を後からのやることではなく、作業の一部として扱ってください。

静的分析はここでも役立ちます。CodeSceneのようなツールは、どのファイルが最も複雑な条件ロジックを運ぶかを示すことができます。これは通常、古いフラグがクラスターする場所です。SonarQubeは、チェックを削除した後の到達不可能でデッドコードにフラグが付けられます。

フラグの背後にあるコードをどのようにテストするか

テストは、誰も予算を立てない部分です。フラグあたり2つのパスを使用して、テストスイートは両方をカバーする必要があります。少なくとも危険な動作を保護するフラグの場合。

実用的に保ってください。ユニットテストで、フラグ値を注入して、ライブサービスを読むのではなく、すべてのリリースフラグのオンとオフの状態をテストします。デフォルトの本番構成に対して1つのエンドツーエンドスイートを実行してください。これは、今日ユーザーが取得するものです。次に、リリースするために機能フラグをオンにして2回目のパスを実行します。

すべての組み合わせをテストしようとしないでください。10個のフラグでは、あなたはできません。代わりに、フラグを独立させてください。別のフラグもオンの場合にのみ動作が変わるフラグは設計の臭いです。これは、分解する最初のものです。

エンジニアは何を誤解しているか

ジュニアは同じ3つの間違いをします。それぞれはレビューで安く予防できます。

新規雇用の最初の2週間は、彼らが所有者なしの古いフラグに実行する場合です。タイプ、所有者、各エントリの削除日を持つ短いフラグレジストリは、何時間もの周りを聞くことを節約します。

フィーチャーフラグをスキップすべき時

フラグは無料ではないため、次の場合はスキップしてください。

そして、変更が危険で、ユーザー向けで、再配置によって元に戻すのが難しい場合は、躊躇なくそれらを使用してください。支払いの流れ、認証の変更、およびそれの背後にあるデータ移行はすべて適格です。

10人のチームで実際に何をするか

設定にブール値と1つのラッパー関数を使用して開始し、すべてのフラグ読み込みが1つの場所を通過するようにします。その単一のチョークポイントにより、フラグリストが検索可能、監査可能、後でホストされたサービスに移行しやすくなります。

各フラグをタイプで、所有者を付けてラベルを付け、1日目の削除チケットを提出します。月に1回、10分でリストを確認してください。2週間100%にあったフラグを削除します。

フィーチャーフラグはローンです。危険なリリースを節約するとき、そしてインタレストが次のリファクタリングで表示される前にそれを返すときに摂取してください。

よくある質問

フィーチャーフラグはなぜ必要なのか
トランク・ベース開発での安全なマージ、段階的なロールアウト、問題時の素早い復旧が可能になります。ベンダーソリューション不要で、設定ファイルのブール値から始められます。
フィーチャーフラグにはどのような種類があるか
Pete Hodgsonの分類では4タイプあります。リリース(数日~数週間)、実験(数週間)、Ops(数時間~永遠)、パーミッション(数ヶ月~数年)。有効期限が最も重要な指標です。
フィーチャーフラグの技術的負債問題とは
10個のフラグで1,024の可能なコードパスが生じ、テストが追いつきません。GrowthBookの研究では75%のトグルが49週間後も削除されていません。Knight Capital事件(2012年、4億6000万ドル損失)は、古いフラグ再利用の危険性を示します。
フラグのクリーンアップ戦略は何か
作成時に削除チケットを作成し、所有者と有効期限を設定。90日以上変更なしは削除対象。2つのプルリクエストで段階的に削除し、時限爆弾テストと合計数の上限を維持します。
既存のコードベースで全フラグを検索する方法は
正規表現検索は文字列連結に対応できず、マルチレポ環境では不十分です。CursorやGitHub Copilotで単一リポをカバーし、複数リポにはコード検索インデックスが必要です。
フラグの背後のコードはどのようにテストするか
リリースフラグのオン・オフをユニットテストで、デフォルト本番構成でエンドツーエンドテストを実行。フラグを独立させ、組み合わせテストを避けます。
フィーチャーフラグをスキップすべき場合は
変更が小さく可逆的で、1回のデプロイでロールバック可能な場合。データベーススキーマ変更やフラグ削除プロセスのないチームの場合。