銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

OpenFeature .NET SDKを試してみた(1)

OpenFeatureとは

OpenFeatureは2023年12月CNCFのincubationプロジェクトに昇格したプロジェクトです。以下の記事の冒頭を翻訳して引用する形でOpenFeatureを紹介します。

www.cncf.io

OpenFeature は、さまざまな機能フラグ管理ツールと互換性のある、機能フラグ設定用のベンダーに依存しないコミュニティ主導の API を提供するオープン仕様です。機能フラグは、チームがソース コードを変更せずに、製品またはサービスの特定の機能またはコード パスの動作を有効化、無効化、または変更できるようにするソフトウェア開発の手法です。

OpenFeature による機能フラグの標準化により、共通インターフェイスの背後でツールとベンダーが統合され、コード レベルでのベンダー ロックインを回避し、コミュニティ全体で共有できる拡張機能や統合を構築するためのフレームワークが提供されます。

もし機能フラグが1つしかなかったり、複数あっても担当するチームとソフトウェアが独立していれば、データベースなり環境変数に値を保存した値を取り出すコードとif文、そして関数呼び出しだけで済むはずです。が、なぜわざわざ標準化が必要なのかというのはOpenFeatureのブログに書かれています。

openfeature.dev

このOpenFeatureを .NET アプリの中で利用できるSDKがOpenFeature .NET SDK です。何回かに分けてこのSDKを試してみたいと思います。

github.com

OpenFeature .NET SDKを試す

flagdを動かす

サンプルコードを動かそうとするといきなり問題にあたります。InMemoryProviderというクラスが見つからないからです。Issueが立っていて実は未実装です。

github.com

Providerというのは後述しますがフラグの値を評価するレイヤーで、フラグの値を管理しているツールとSDK間の問い合わせを抽象化します。InMemoryProviderはその名の通りメモリ上にフラグの値を保管するものなのでお試しするには使いやすいですが、運用する際には別のものに置き換えられるはずです。間もなく実装されることを期待して、今回は別のProviderを使うことにします。

OpenFeature .NET SDKで利用可能なプロバイダーの一覧はこちらにありますが、今回はDockerですぐに起動できるflagdを使ってみました。

openfeature.dev

github.com

flagdはDockerで動くので、以下の手順に従ってフラグの値のJSONファイルを準備し起動します。

flagd.dev

PowerShellで起動する場合はこうです。

docker run --rm -it --name flagd -p 8013:8013 -v ${PWD}:/etc/flagd ghcr.io/open-feature/flagd:latest start --uri file:./etc/flagd/demo.flagd.json

.NET アプリ側でコードを記述する

これでSDKが利用できます。SDK本体を利用するにはOpenFeatureというNuGetライブラリを、さらにflagdをプロバイダーとして利用するためにOpenFeature.Contrib.Providers.Flagdというライブラリを参照します。

<PackageReference Include="OpenFeature" Version="1.3.1" />
<PackageReference Include="OpenFeature.Contrib.Providers.Flagd" Version="0.1.7" />

サンプルコードは以下のようになります。おそらく実際にはアプリケーションの中で一度プロバイダーの作成と登録を行い、必要な場所でクライアントの作成と機能フラグの値の取得を行うことになります。

using OpenFeature;
using OpenFeature.Contrib.Providers.Flagd;

//プロバイダーを作成する(今回はflagdの接続先のみをオプションで指定)
var flagdProvider = new FlagdProvider(new Uri("http://localhost:8013"));
//プロバイダーを登録する
Api.Instance.SetProvider(flagdProvider);
//クライアントを作成する
var client = Api.Instance.GetClient();
//機能フラグの値を取得する。第2引数はデフォルト値。
var val = await client.GetBooleanValue("show-welcome-banner", false);
Console.WriteLine(val.ToString());

プロバイダーとは

OpenFeatureのプロバイダーはフラグ評価の責務を持っており、OpenFeature SDKのAPI呼び出しに応じてフラグ管理システムに問い合わせて値を返します。今回の場合はコンテナで動いているflagdに問い合わせてその結果を返しているため、上の例ではTrueが表示されます。

openfeature.dev

OpenFeatureではプロバイダーは1つしか登録できずあと勝ちになります。また、プロバイダーを登録していない場合やフラグの名前が存在しない場合は、第2引数で指定したデフォルト値が返されます。 また、プロバイダーを開発することもできます。まだOpenFeatureに対応していないフラグ管理システムのSDKのブリッジとしてや、自分たちで管理しているデータベースやファイルシステムへの問い合わせをProviderとして抽象化することができます。