春をめくるためのガイド

春のフリップガイド

1. 概要

このチュートリアルでは、Spring Core、Spring MVC、およびSpring Bootアプリケーション用の強力なアノテーションの形式で機能フラグを実装するライブラリのFlips,について説明します。

機能フラグ(またはトグル)は、新しい機能を迅速かつ安全に提供するためのパターンです。 これらの切り替えにより、アプリケーションの動作を変更できますwithout changing or deploying new code. Martin Fowlerのブログには、機能フラグhereに関する非常に有益な記事があります。

2. メーベン依存

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


    com.github.feature-flip
    flips-core
    1.0.1

Maven Centralにはlatest version of the libraryがあり、Githubプロジェクトはhereです。

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


    org.springframework.boot
    spring-boot-starter-web
    1.5.10.RELEASE

FlipsはまだSpringバージョン5.xと互換性がないため、latest version of Spring Boot in the 4.x branchを使用します。

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

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

RESTアプリケーションは、Fooリソースへのアクセスを提供します。

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

Foosのリストを維持するServiceを作成するだけです。

@Service
public class FlipService {

    private List foos;

    public List 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 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.idYの場合、IDでリクエストできます。 定義されていない(またはまったく定義されていない)場合、Flipsは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.example.flips.model.Foo
      com.example.flips.controller.FlipController.getFooById(int)",
    "className":"com.example.flips.controller.FlipController",
    "featureName":"getFooById"
}

予想どおり、SpringはFeatureNotEnabledExceptionをキャッチし、ステータス501をクライアントに返します。

4.2. アクティブプロファイル

Springは長い間、Beanをdevtestprodなどのさまざまなprofilesにマップする機能を提供してきました。 この機能を拡張して、機能フラグをアクティブなプロファイルにマッピングすることは直感的です。

アクティブなSpring Profileに基づいて、機能がどのように有効または無効になるかを見てみましょう。

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

@FlipOnProfilesアノテーションは、プロファイル名のリストを受け入れます。 アクティブなプロファイルがリストにある場合、APIにアクセスできます。

4.3. 春の式

Spring’s Expression Language (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は、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. トグルの組み合わせ

複数を指定してトグルを組み合わせます。 フリップは、暗黙的な「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を交換することで機能を切り替える方法を確認しました。

いつものように、コードサンプルはover on GitHubで見つけることができます。