1概要

このチュートリアルでは、https://github.com/Feature-Flip/flips[Flips、]Spring Core、Spring MVC、およびSpring Bootの強力なアノテーションの形で機能フラグを実装するライブラリを見ていきます。アプリケーション

機能フラグ(またはトグル)は、新しい機能を迅速かつ安全に提供するためのパターンです。 Martin Fowler氏のブログには、機能フラグに関する非常に有益な記事がありますhttps://martinfowler.com/articles/feature-toggles.html[ここ]。


2 Mavenの依存関係

始める前に、Flipsライブラリを__pom.xmlに追加する必要があります。

<dependency>
    <groupId>com.github.feature-flip</groupId>
    <artifactId>flips-core</artifactId>
    <version>1.0.1</version>
</dependency>

Maven Centralにはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.github.feature-flip%22[最新版のライブラリー]があり、Githubプロジェクトはhttpsです。 ://github.com/Feature-Flip/flips[ここ]。

もちろん、Springも含める必要があります。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.5.10.RELEASE</version>
</dependency>

FlipsはまだSpringバージョン5.xと互換性がないので、https://search.maven.org/classic/#artifactdetails%7Corg.springframework.boot%7Cspring-boot-starter-web%を使用します7C1.5.10.RELEASE%7Cjar[4.xブランチのSpring Bootの最新バージョン]。


3フリップ用のシンプルなRESTサービス

新しい機能とフラグを追加したり切り替えたりするための簡単なSpring Bootプロジェクトをまとめましょう。

私たちのRESTアプリケーションは

Foo

リソースへのアクセスを提供します。

public class Foo {
    private String name;
    private int id;
}


Foos

のリストを管理する

Service

を作成するだけです。

@Service
public class FlipService {

    private List<Foo> foos;

    public List<Foo> getAllFoos() {
        return foos;
    }

    public Foo getNewFoo() {
        return new Foo("New Foo!", 99);
    }
}

ここでは追加のサービスメソッドを参照しますが、このスニペットは

FlipService

がシステム内で何をするのかを説明するのに十分なはずです。

そしてもちろん、コントローラを作成する必要があります。

@RestController
public class FlipController {

    private FlipService flipService;

   //constructors

    @GetMapping("/foos")
    public List<Foo> getAllFoos() {
        return flipService.getAllFoos();
    }
}


4構成に基づく制御機能

Flipsの最も基本的な使い方は、設定に基づいて機能を有効または無効にすることです。 Flipsにはこれに関するいくつかの注釈があります。


4.1. 環境特性


FlipService

に新しい機能が追加されたとします。自分のIDで

Foos

を取得しています。

新しいリクエストをコントローラに追加しましょう。

@GetMapping("/foos/{id}")
@FlipOnEnvironmentProperty(
  property = "feature.foo.by.id",
  expectedValue = "Y")
public Foo getFooById(@PathVariable int id) {
    return flipService.getFooById(id)
      .orElse(new Foo("Not Found", -1));
}


@ FlipOnEnvironmentProperty

は、このAPIが利用可能かどうかを制御します。

簡単に言うと、

feature.foo.by.id



Y

の場合、Idでリクエストを送信できます。

定義されていない場合(またはまったく定義されていない場合)、フリップするとAPIメソッドが無効になります。

  • 機能が有効になっていない場合、Flipsは

    FeatureNotEnabledException

    をスローし、SpringはRESTクライアントに “未実装”を返します。

プロパティを

N

に設定してAPIを呼び出すと、次のようになります。

Status = 501
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {
    "errorMessage": "Feature not enabled, identified by method
      public com.baeldung.flips.model.Foo
      com.baeldung.flips.controller.FlipController.getFooById(int)",
    "className":"com.baeldung.flips.controller.FlipController",
    "featureName":"getFooById"
}

予想通り、Springは

FeatureNotEnabledException

をキャッチし、ステータス501をクライアントに返します。


4.2. アクティブなプロフィール

Springは長い間、

dev



test



prod

など、さまざまなリンク:/spring-profiles[profiles]にマップする機能を提供してきました。

この機能を拡張して機能フラグをアクティブプロファイルにマッピングすることで、直感的に理解できるようになります。

アクティブリンクに基づいて機能がどのように有効または無効になるかを見てみましょう:/spring-profiles[Spring Profile]:

@RequestMapping(value = "/foos", method = RequestMethod.GET)
@FlipOnProfiles(activeProfiles = "dev")
public List getAllFoos() {
    return flipService.getAllFoos();
}


@ FlipOnProfiles

注釈は、プロファイル名のリストを受け入れます。アクティブプロファイルがリストにある場合は、APIにアクセスできます。


4.3. 春の表現


Springの式言語(SpEL)

は、ランタイム環境を操作するための強力なメカニズムです。 Flipsには機能を切り替える方法もあります。


@ FlipOnSpringExpression

は、ブール値を返すSpEL式に基づいてメソッドを切り替えます。

新しい機能を制御するために簡単な式を使用しましょう。

@FlipOnSpringExpression(expression = "(2 + 2) == 4")
@GetMapping("/foo/new")
public Foo getNewFoo() {
    return flipService.getNewFoo();
}


4.4. 無効にする

機能を完全に無効にするには、

@ FlipOff

を使用します。

@GetMapping("/foo/first")
@FlipOff
public Foo getFirstFoo() {
    return flipService.getLastFoo();
}

この例では、

getFirstFoo()

は完全にアクセス不能です。

以下に示すように、Flipsアノテーションを組み合わせることで、

@ FlipOff

を使用して環境やその他の基準に基づいて機能を無効にすることができます。


5日付/時刻で機能を制御する

フリップは、日付/時刻または曜日に基づいて機能を切り替えることができます。

新機能の可用性を日にちまたは日付に結び付けることには、明らかな利点があります。


5.1. 日時


@ FlipOnDateTime

は、https://www.iso.org/iso-8601-date-and-time-format.html[ISO 8601]の形式でフォーマットされたプロパティの名前を受け入れます。

では、3月1日に有効になる新機能を示すプロパティを設定しましょう。

first.active.after=2018-03-01T00:00:00Z

それでは、最初のFooを取得するためのAPIを書きます。

@GetMapping("/foo/first")
@FlipOnDateTime(cutoffDateTimeProperty = "first.active.after")
public Foo getFirstFoo() {
    return flipService.getLastFoo();
}

反転すると、名前付きプロパティがチェックされます。プロパティが存在し、指定された日時が経過した場合、機能は有効になります。


5.2. 曜日

ライブラリは

@ FlipOnDaysOfWeek

を提供します。これはA/Bテストなどの操作に役立ちます。

@GetMapping("/foo/{id}")
@FlipOnDaysOfWeek(daysOfWeek={DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY})
public Foo getFooByNewId(@PathVariable int id) {
    return flipService.getFooById(id).orElse(new Foo("Not Found", -1));
}


getFooByNewId()

は月曜日と水曜日にのみ利用可能です。


6. Beanを交換する

メソッドのオンとオフの切り替えは便利ですが、新しいオブジェクトを介して新しい動作を導入したい場合があります。

@ FlipBean

は、新しいBeanのメソッドを呼び出すようにFlipsに指示します。

FlipsアノテーションはどのSpringにも作用することができます

@Component.

これまでのところ、私たちは

@ RestController

を変更しただけなので、

Service.

を変更してみましょう。


FlipService

とは異なる動作を持つ新しいサービスを作成します。

@Service
public class NewFlipService {
    public Foo getNewFoo() {
        return new Foo("Shiny New Foo!", 100);
    }
}

古いサービスの

getNewFoo()

を新しいバージョンに置き換えます。

@FlipBean(with = NewFlipService.class)
public Foo getNewFoo() {
    return new Foo("New Foo!", 99);
}

反転すると、

getNewThing()

の呼び出しが__NewFlipServiceに転送されます。

@FlipBean__は、他のトグルと組み合わせると最も便利なもう1つの切り替えです。今それを見てみましょう。


7. トグルの組み合わせ

複数を指定してトグルを組み合わせます。 Flipsはこれらを暗黙の “AND”論理で順番に評価します。したがって、これらの機能すべてをオンにするには、それらのすべてが真でなければなりません。

前の2つの例を組み合わせてみましょう。

@FlipBean(
  with = NewFlipService.class)
@FlipOnEnvironmentProperty(
  property = "feature.foo.by.id",
  expectedValue = "Y")
public Foo getNewFoo() {
    return new Foo("New Foo!", 99);
}

設定可能な新しいサービスを利用しました。


8結論

この簡単なガイドでは、シンプルなSpring Bootサービスを作成し、Flipsアノテーションを使用してAPIのオンとオフを切り替えました。設定情報と日付/時刻を使用して機能を切り替える方法、および実行時にBeanを交換することで機能を切り替える方法を確認しました。

いつものように、コードサンプルはhttps://github.com/eugenp/tutorials/tree/master/spring-4[over GitHub]にあります。