この記事は、CYBOZU SUMMER BLOG FES '24 (kintone Stage) DAY 3の記事です。
こんにちは、kintoneチームの川向です。
今回は簡単に使えるフィーチャーフラグシステムのGO Feature Flagを紹介します。
フィーチャーフラグとは
フィーチャーフラグは、コードを変えずに挙動を切り替える仕組みです。
コードのイメージはこちらです。newFeatureFlag.enabled()
の結果が外部の設定ファイルやフィーチャーフラグシステムの設定によって変わり、それによって機能を切り替えます。
if ( newFeatureFlag.enabled() ) { newFeature(); } else { oldFeature(); }
これにより、新しい機能の一部のユーザへの段階的公開や、A/Bテストなどが可能になります。
フィーチャーフラグシステム: GO Feature Flag
フィーチャーフラグの仕組みはそれほど複雑ではないので自前で実装することもできますが、SaaSやOSSもあります。LaunchDarklyやUnleashなどが有名です。
今回はすぐに使えるOSSのフィーチャーフラグシステムのGO Feature Flagを紹介します。
GO Feature Flagは以下のような特徴があります:
- 設定ファイルでフラグを制御する。DBを使用しないので、運用が容易
- フラグの公開制御が柔軟に行える
- 複数言語のSDKがある
- GO Feature Flag relay proxyというHTTPサーバーが提供されている
- OpenFeatureをサポートしている
relay proxyを使った場合のシステム構成はこのようになります。
使ってみよう
さっそく簡単なフラグをGO Feature Flagで使ってみましょう。
GO Feature Flag relay proxyの準備
まずは設定ファイルを2つ用意します。
# goff-proxy.yaml # GO Feature Flag relay proxyの設定ファイル retriever: kind: file path: /goff/flag.goff.yaml # flag.goff.yaml # フラグの定義ファイル # newFeatureFlagというtrueかfalseを返すフラグを定義している newFeatureFlag: variations: enable: true disable: false # 初期値はdisable(値はfalse) defaultRule: variation: disable
GO Feature Flagのrelay proxyをdockerで起動します。 先程の設定ファイルはワーキングディレクトリに配置している想定です。
$ docker run -v $(pwd)/goff:/goff/ -p 1031:1031 \ gofeatureflag/go-feature-flag:v1.31.1 █▀▀ █▀█ █▀▀ █▀▀ ▄▀█ ▀█▀ █ █ █▀█ █▀▀ █▀▀ █ ▄▀█ █▀▀ █▄█ █▄█ █▀ ██▄ █▀█ █ █▄█ █▀▄ ██▄ █▀ █▄▄ █▀█ █▄█ █▀█ █▀▀ █ ▄▀█ █▄█ █▀█ █▀█ █▀█ ▀▄▀ █▄█ █▀▄ ██▄ █▄▄ █▀█ █ █▀▀ █▀▄ █▄█ █ █ █ GO Feature Flag Relay Proxy _____________________________________________ {"level":"info","ts":1721955130.511597,"msg":"flag added","key":"newFeatureFlag"} {"level":"info","ts":1721955130.511656,"caller":"api/server.go:115","msg":"Starting go-feature-flag relay proxy ...","address":"0.0.0.0:1031","version":"1.31.1"}
これで準備OKです。
JavaからGO Feature Flag relay proxyを参照する
次にGO Feature Flagを参照するコードを書いてみます。 今回はGO Feature FlagのJava SDKのページを参考に、Javaで書いてみます。
まずはライブラリのインストールを行います。 今回はGradleを使うので、build.gradleに以下を追記します。
implementation group: 'dev.openfeature', name: 'javasdk', version: '1.9.0' implementation group: 'dev.openfeature.contrib.providers', name: 'go-feature-flag', version: '0.2.23'
いよいよこれを参照するコードを書きます。
// GO Feature Flagの設定 GoFeatureFlagProviderOptions options = GoFeatureFlagProviderOptions.builder().endpoint("http://localhost:1031/").build(); GoFeatureFlagProvider provider = new GoFeatureFlagProvider(options); // OpenFeatureAPIへの登録 OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProviderAndWait(provider); // 登録が完了するのを待つ Client featureFlagClient = api.getClient(); // Contextの設定 String targetingKey = "abc"; // 何らかのユニークな値を指定する EvaluationContext userContext = new MutableContext(targetingKey) .add("username", "john"); // 値の取得 Boolean newFeatureFlag = featureFlagClient.getBooleanValue("newFeatureFlag", false, userContext); if (newFeatureFlag) { newFeature(); } else { oldFeature(); } // 終了処理 api.shutdown();
これでフィーチャーフラグを使って機能を制御できるようになりました。
もとの設定ではdisable(値はfalse)だったので、oldFeature()
が実行されます。
flag.goff.yaml
を以下のように書き換えてrelay proxyを再起動すると、フラグがenable(値はtrue)に変わります。この状態で再度実行するとnewFeature()
が実行されます。
... defaultRule: - variation: disable + variation: enable
他にもできること
先程の例のフラグは単純なON/OFFを切り替えるだけでしたが、 条件に応じて値を変えることもできます。
# flag.goff.yaml # 特定のユーザーだけ新機能を有効化する newFeatureFlag: variations: enable: true disable: false defaultRule: variation: disable targeting: # Contextで渡した値をもとにした条件を書くことができる # 条件に合致したときだけ評価値を変える事ができる - name: Johnだけ機能を有効にする query: username eq "john" variation: enable
A/Bテストのように、割合に応じた制御もできます。
# flag.goff.yaml colorFlag: variations: yellow: "#FFFF00" green: "#008000" defaultRule: # 70%のユーザでyellowを選択し、30%のユーザでgreenを選択する percentage: yellow: 70 green: 30
先程の例ではローカルファイルを直接参照していましたが、外部(S3やHTTP、GitHub)のファイルも取得できます。
# goff-proxy.yaml retriever: # HTTP経由でフラグの設定ファイルを参照する kind: http url: https://example.com/flag.goff.yaml
OpenFeatureや他のフィーチャーフラグシステムについて
GO Feature FlagはOpenFeatureという仕様に沿っています。これはフィーチャーフラグの標準として策定が行われているものです。
このため、GO Feature Flagから他のツールに移行するときも、OpenFeatureに対応しているものであればproviderを差し替えるだけでOKです。
OpenFatureに対応しているフィーチャーフラグシステムは公式サイトで紹介されています。 前述のLaunchDarklyやUnleashのproviderもあります。
まとめ
フィーチャーフラグとそれを実現するGO Feature Flagを紹介しました。
GO Feature Flagは他にも様々な機能があります。 KubernetesやAWSでの運用方法なども公式サイトで紹介されているので、 気になる方はぜひ調べてみてください。