フィーチャートグルの実装


1. Feature Toggle の基本管理クラス

Feature Toggle を管理するためのサービスを作成します。この例では機能の有効/無効だけでなく、複数の戦略をエミュレートできる設計です。

// Java
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
@Service
public class FeatureToggleService {
// トグルごとの状態を管理するマップ(必要なら別の戦略を追加可)
private final Map<String, Supplier<Boolean>> toggles = new HashMap<>();
// 初期化(デフォルトの状態を設定)
public FeatureToggleService() {
// 固定トグル(true 固定で有効)
toggles.put("newFeature", () -> true);
// 動的な戦略(例えば、時間に応じたフラグなども設定可)
toggles.put("betaFeature", () -> System.currentTimeMillis() % 2 == 0); // 条件: 偶数ミリ秒のみ有効
// フラグが無効の場合も考慮
toggles.put("legacyFeature", () -> false);
}
// トグルの状態を取得
public boolean isFeatureActive(String featureName) {
return toggles.getOrDefault(featureName, () -> false).get();
}
// 新しいトグルの動的な追加
public void addFeatureToggle(String featureName, Supplier<Boolean> strategy) {
toggles.put(featureName, strategy);
}
}

2. Feature Toggle の利用例 (サービスクラスで活用)

サービスロジックで FeatureToggleService を利用し、機能を動的に切り替えます。

// Java
import org.springframework.stereotype.Service;
@Service
public class BusinessService {
private final FeatureToggleService featureToggleService;
// コンストラクタによる依存性注入
public BusinessService(FeatureToggleService featureToggleService) {
this.featureToggleService = featureToggleService;
}
// 機能を動的に切り替えながら処理を実行
public void executeFeature() {
if (featureToggleService.isFeatureActive("newFeature")) {
System.out.println("新機能が有効です: 新しい処理を実行します!");
} else {
System.out.println("新機能は無効です: 従来の処理を実行します。");
}
if (featureToggleService.isFeatureActive("betaFeature")) {
System.out.println("ベータ機能が有効です: この機能を一部のユーザーに提供します。");
}
}
}

3. コントローラーで Feature Toggle を操作する例

エンドユーザーが Feature Toggle を動的に有効化または無効化できるようなエンドポイントを提供します。

// Java
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/toggles")
public class FeatureToggleController {
private final FeatureToggleService featureToggleService;
// コンストラクタによる依存性注入
public FeatureToggleController(FeatureToggleService featureToggleService) {
this.featureToggleService = featureToggleService;
}
// 特定のトグルの状態を取得
@GetMapping("/{featureName}")
public Map<String, Boolean> getFeatureStatus(@PathVariable String featureName) {
boolean isActive = featureToggleService.isFeatureActive(featureName);
return Map.of(featureName, isActive);
}
// 新しいトグルを追加
@PostMapping("/{featureName}/add")
public String addFeatureToggle(@PathVariable String featureName, @RequestParam boolean defaultState) {
featureToggleService.addFeatureToggle(featureName, () -> defaultState);
return "Feature toggle " + featureName + " added with default state: " + defaultState;
}
}

4. 使用例

以下は、実際のAPIやサービスを通じた使い方の例です。

特定のトグルの状態を確認

エンドポイント:

  • GET /api/toggles/newFeature

レスポンス例:

{
"newFeature": true
}

トグルを動的に追加

エンドポイント:

  • POST /api/toggles/experimentalFeature/add?defaultState=true

レスポンス:

Feature toggle experimentalFeature added with default state: true

機能実行時の動作確認

// 呼び出し例 (手動テスト)
BusinessService service = new BusinessService(new FeatureToggleService());
service.executeFeature();

ターミナル出力例(時間やトグルに依存):

新機能が有効です: 新しい処理を実行します!
ベータ機能が有効です: この機能を一部のユーザーに提供します。

5. 改善ポイント

  • 外部設定の導入 (Spring Config): Feature Toggle の設定を外部のプロパティファイルやデータベースで管理する。
  • トグル戦略の多様化:
    利用者ごと、リクエストごと、または特定の条件(例: リクエストヘッダや地理情報)に応じた戦略を実装可能。
  • Feature Toggle ライブラリの利用:
    業務規模が大きくなる場合、FF4JUnleash を検討。

以上は、Spring を用いた基本的な Feature Toggle 実装のサンプルです。要件に応じて調整・拡張してください!

User: プロパティファイルを使う

Assistant: Spring Framework で プロパティファイル (application.properties or application.yml) を使用して Feature Toggle を実現する場合の実装例を以下に示します。この方法では、プロパティファイルでトグルを設定し、それをサービスやビジネスロジックで参照できるようにします。


1. プロパティファイルでトグル状態を定義

application.properties または application.yml に Feature Toggle の状態を定義します。

application.properties

feature.newFeature=true
feature.betaFeature=false
feature.legacyFeature=true

application.yml

feature:
newFeature: true
betaFeature: false
legacyFeature: true

2. プロパティを管理するクラスを作成

Spring の @ConfigurationProperties アノテーションを使用し、プロパティを簡単に管理できるようにします。

// Java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "feature")
public class FeatureToggleProperties {
private boolean newFeature;
private boolean betaFeature;
private boolean legacyFeature;
// ゲッターとセッター
public boolean isNewFeature() {
return newFeature;
}
public void setNewFeature(boolean newFeature) {
this.newFeature = newFeature;
}
public boolean isBetaFeature() {
return betaFeature;
}
public void setBetaFeature(boolean betaFeature) {
this.betaFeature = betaFeature;
}
public boolean isLegacyFeature() {
return legacyFeature;
}
public void setLegacyFeature(boolean legacyFeature) {
this.legacyFeature = legacyFeature;
}
}

注意: @ConfigurationProperties を使用するためには、spring-boot-configuration-processor を依存関係に追加しておく必要があります。


3. Feature Toggle を使用するサービスクラス

上記で定義したプロパティ管理クラスを使用して、フィーチャーの有効/無効をチェックします。

// Java
import org.springframework.stereotype.Service;
@Service
public class BusinessService {
private final FeatureToggleProperties featureToggleProperties;
// コンストラクタインジェクション
public BusinessService(FeatureToggleProperties featureToggleProperties) {
this.featureToggleProperties = featureToggleProperties;
}
// 機能の実行
public void executeFeature() {
if (featureToggleProperties.isNewFeature()) {
System.out.println("新機能が有効です: 新しい処理を実行します!");
} else {
System.out.println("新機能は無効です: 従来の処理を実行します。");
}
if (featureToggleProperties.isBetaFeature()) {
System.out.println("ベータ機能が有効です: 特定の機能にアクセス可能です。");
} else {
System.out.println("ベータ機能は無効です: ロックされています。");
}
}
}

4. コントローラーでトグルの状態を確認

REST API を提供し、動的にプロパティ値を確認・変更できる仕組みを追加することができます。

// Java
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/features")
public class FeatureToggleController {
private final FeatureToggleProperties featureToggleProperties;
// コンストラクタインジェクション
public FeatureToggleController(FeatureToggleProperties featureToggleProperties) {
this.featureToggleProperties = featureToggleProperties;
}
// 現在のフィーチャートグルの状態を取得
@GetMapping
public FeatureToggleProperties getFeatureToggles() {
return featureToggleProperties; // 現在のプロパティすべてを返す
}
// フィーチャートグルの特定の値を動的に変更する例(開発・テスト向け)
@PostMapping("/{featureName}/toggle")
public String toggleFeature(@PathVariable String featureName, @RequestParam boolean enabled) {
switch (featureName) {
case "newFeature":
featureToggleProperties.setNewFeature(enabled);
break;
case "betaFeature":
featureToggleProperties.setBetaFeature(enabled);
break;
case "legacyFeature":
featureToggleProperties.setLegacyFeature(enabled);
break;
default:
return "Feature not found: " + featureName;
}
return "Feature " + featureName + " set to " + enabled;
}
}

5. 使用例

フィーチャートグルの状態を確認

エンドポイント:

  • GET /api/features

レスポンス例:

{
"newFeature": true,
"betaFeature": false,
"legacyFeature": true
}

トグルを変更

エンドポイント:

  • POST /api/features/newFeature/toggle?enabled=false

レスポンス:

Feature newFeature set to false

トグルを活用した処理

サービスでフィーチャートグルを切り替えながら呼び出します。

// Example: Call service
BusinessService service = new BusinessService(new FeatureToggleProperties());
service.executeFeature();

結果:

新機能が有効です: 新しい処理を実行します!
ベータ機能は無効です: ロックされています。

6. 改善案

  1. プロパティの再読込

    • Spring Actuator を使用することで、プロパティを動的にリロードする(@RefreshScope を利用)。
    • 外部設定管理ツール(例: Spring Cloud Config Server, Consul, Zookeeper)を活用する。
  2. ロジックの複雑化に対応

    • トグルの条件を単純な真偽値として管理するのではなく、「User ID」「リクエストのヘッダー情報」など複雑な条件で判断できるよう抽象化する。