Рубрики
Без рубрики

Руководство по сальто для весны

Узнайте о Flips, библиотеке, которая реализует флаги функций в виде мощных аннотаций для приложений Spring Core, Spring MVC и Spring Boot.

Автор оригинала: Eric Goebelbecker.

1. Обзор

В этом уроке мы рассмотрим Flips, библиотеку, которая реализует флаги функций в виде мощных аннотаций для приложений Spring Core, Spring MVC и Spring Boot.

Флаги функций (или переключатели) – это шаблон для быстрой и безопасной доставки новых функций. Эти переключатели позволяют нам изменять поведение приложения без изменения или развертывания нового кода. В блоге Мартина Фаулера есть очень информативная статья о флагах функций здесь .

2. Зависимость Maven

Прежде чем мы начнем, нам нужно добавить библиотеку Flips в ваш pom.xml:


    com.github.feature-flip
    flips-core
    1.0.1

Maven Central имеет последнюю версию библиотеки , а проект Github находится здесь .

Конечно, нам также нужно включить пружину:


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

Поскольку Flips еще не совместим с Spring версии 5.x, мы собираемся использовать последнюю версию Spring Boot в ветке 4.x .

3. Простой сервис ОТДЫХА для переворотов

Давайте соберем простой проект Spring Boot для добавления и переключения новых функций и флагов.

Наше приложение REST обеспечит доступ к Продуктам питания ресурсам:

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

Мы просто создадим Сервис , который поддерживает список Продуктов :

@Service
public class FlipService {

    private List foos;

    public List getAllFoos() {
        return foos;
    }

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

Мы будем ссылаться на дополнительные методы обслуживания по ходу работы, но этого фрагмента должно быть достаточно, чтобы проиллюстрировать, что Flip Service делает в системе.

И, конечно, нам нужно создать контроллер:

@RestController
public class FlipController {

    private FlipService flipService;

    // constructors

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

4. Функции управления На основе конфигурации

Самое основное использование Flips-это включение или отключение функции в зависимости от конфигурации. У Flips есть несколько аннотаций для этого.

4.1. Свойство окружающей среды

Давайте представим, что мы добавили новую возможность в Flip Service ; получение Дураков по их идентификатору.

Давайте добавим новый запрос к контроллеру:

@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 is Y , мы можем делать запросы по идентификатору. Если это не так (или вообще не определено), Flips отключит метод API.

Если функция не включена, будут выполняться сальто FeatureNotEnabledException и Spring вернет “Не реализованный” клиенту REST.

Когда мы вызываем API со свойством , установленным в N , это то, что мы видим:

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. Активный профиль

Весна уже давно дала нам возможность сопоставлять бобы с различными профилями , такими как dev , test или prod . Расширение этой возможности для сопоставления флагов функций с активным профилем имеет интуитивный смысл.

Давайте посмотрим, как функции включаются или отключаются в зависимости от активного профиля Spring:

@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();
}

В этом примере get First Foo() полностью недоступен.

Как мы увидим ниже, мы можем комбинировать аннотации Flips, что позволяет использовать @FlipOff для отключения функции в зависимости от среды или других критериев.

5. Функции Управления С Датой/Временем

Сальто может переключать функцию в зависимости от даты/времени или дня недели. Привязка доступности новой функции к дню или дате имеет очевидные преимущества.

5.1. Дата и время

@FlipOnDateTime принимает имя свойства, отформатированного в формате ISO 8601 .

Итак, давайте установим свойство, указывающее на новую функцию, которая будет активна 1 марта:

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

Затем мы напишем API для получения первого Foo:

@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. Замените боб

Включение и выключение методов полезно, но мы можем захотеть ввести новое поведение с помощью новых объектов. @FlipBean направляет Flips для вызова метода в новом компоненте.

Аннотация Flips может работать на любом компоненте Spring @. До сих пор мы только изменили наш @RestController , давайте попробуем изменить наш Сервис.

Мы создадим новый сервис с другим поведением от Флип Сервис :

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

Мы заменим старый сервис get New Foo() на новую версию:

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

Flips будет направлять вызовы в get New Thing() в Новую службу Flip. @FlipBean – это еще один переключатель, который наиболее полезен в сочетании с другими. Давайте посмотрим на это сейчас.

7. Комбинирование переключателей

Мы объединяем переключатели, указывая более одного. Флипс оценивает их последовательно, с неявной логикой “И”. Поэтому все они должны быть истинными, чтобы включить эту функцию.

Давайте объединим два наших предыдущих примера:

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

Мы воспользовались новым сервисом.

8. Заключение

В этом кратком руководстве мы создали простую службу загрузки Spring и включали и выключали API с помощью аннотаций Flips. Мы видели, как функции переключаются с помощью информации о конфигурации и даты/времени, а также как функции могут переключаться путем замены компонентов во время выполнения.

Примеры кода, как всегда, можно найти на GitHub .