Um guia para virar para a primavera

Um guia para virar para a primavera

1. Visão geral

Neste tutorial, daremos uma olhada emFlips, uma biblioteca que implementa sinalizadores de recursos na forma de anotações poderosas para aplicativos Spring Core, Spring MVC e Spring Boot.

Os sinalizadores de recurso (ou alternância) são um padrão para fornecer novos recursos com rapidez e segurança. Essas alternâncias nos permitem modificar o comportamento do aplicativowithout changing or deploying new code. O blog de Martin Fowler tem um artigo muito informativo sobre sinalizadores de recursoshere.

2. Dependência do Maven

Antes de começarmos, precisamos adicionar a biblioteca Flips ao nossopom.xml:


    com.github.feature-flip
    flips-core
    1.0.1

O Maven Central temlatest version of the library, e o projeto Github éhere.

Obviamente, também precisamos incluir uma mola:


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

Como o Flips ainda não é compatível com o Spring versão 5.x, vamos usar olatest version of Spring Boot in the 4.x branch.

3. Um serviço REST simples para flips

Vamos montar um projeto simples de Spring Boot para adicionar e alternar novos recursos e sinalizadores.

Nosso aplicativo REST fornecerá acesso aos recursosFoo:

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

Vamos simplesmente criar umService que mantém uma lista deFoos:

@Service
public class FlipService {

    private List foos;

    public List getAllFoos() {
        return foos;
    }

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

Faremos referência a métodos de serviço adicionais à medida que avançarmos, mas este snippet deve ser suficiente para ilustrar o queFlipService faz no sistema.

E, claro, precisamos criar um Controller:

@RestController
public class FlipController {

    private FlipService flipService;

    // constructors

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

4. Recursos de controle com base na configuração

O uso mais básico do Flips é ativar ou desativar um recurso com base na configuração. Flips tem várias anotações para isso.

4.1. Propriedade Ambiental

Vamos imaginar que adicionamos um novo recurso aFlipService; recuperandoFoos por seu id.

Vamos adicionar a nova solicitação ao controlador:

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

O@FlipOnEnvironmentProperty controla se esta API está ou não disponível.

Simplificando, quandofeature.foo.by.id éY, podemos fazer solicitações por Id. Se não estiver (ou não estiver definido), o Flips desabilitará o método API.

Se um recurso não estiver habilitado, Flips lançaráFeatureNotEnabledExceptione Spring retornará "Não implementado" para o cliente REST.

Quando chamamos a API com a propriedade definida comoN, isso é o que vemos:

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"
}

Como esperado, o Spring capturaFeatureNotEnabledExceptione retorna o status 501 para o cliente.

4.2. Perfil Ativo

Há muito tempo, o Spring nos dá a capacidade de mapear beans emprofiles diferentes, comodev,test ouprod. Expandir esse recurso para mapear sinalizadores de recursos para o perfil ativo faz sentido intuitivo.

Vamos ver como os recursos são habilitados ou desabilitados com base noSpring Profile ativo:

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

A anotação@FlipOnProfiles aceita uma lista de nomes de perfil. Se o perfil ativo estiver na lista, a API estará acessível.

4.3. Spring Expressions

Spring’s Expression Language (SpEL) é o mecanismo poderoso para manipular o ambiente de execução. O Flips também nos permite alternar recursos com ele.

@FlipOnSpringExpression alterna um método baseado em uma expressão SpEL que retorna um booleano.

Vamos usar uma expressão simples para controlar um novo recurso:

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

4.4. Desativar

Para desativar um recurso completamente, use@FlipOff:

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

Neste exemplo,getFirstFoo() está completamente inacessível.

Como veremos abaixo, podemos combinar anotações Inverter, tornando possível usar@FlipOff para desativar um recurso com base no ambiente ou outros critérios.

5. Recursos de controle com data / hora

Os flips podem alternar um recurso com base em uma data / hora ou no dia da semana. Amarrar a disponibilidade de um novo recurso ao dia ou data tem vantagens óbvias.

5.1. Data e hora

@FlipOnDateTime aceita o nome de uma propriedade formatada no formatoISO 8601.

Então, vamos definir uma propriedade indicando um novo recurso que estará ativo em 1º de março:

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

Em seguida, escreveremos uma API para recuperar o primeiro Foo:

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

Flips irá verificar a propriedade nomeada. Se a propriedade existir e a data / hora especificada tiverem passado, o recurso será ativado.

5.2. Dia da semana

A biblioteca fornece@FlipOnDaysOfWeek, que é útil para operações como testes 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() está disponível apenas às segundas e quartas-feiras.

6. Substitua um Feijão

Ativar e desativar métodos é útil, mas podemos introduzir um novo comportamento por meio de novos objetos. @FlipBean direciona Flips para chamar um método em um novo bean.

Uma anotação Flips pode funcionar em qualquer Spring@Component.. Até agora, só modificamos nosso@RestController, vamos tentar modificar nossoService.

Criaremos um novo serviço com comportamento diferente deFlipService:

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

Vamos substituir ogetNewFoo() do serviço antigo pela nova versão:

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

Inverter irá direcionar chamadas paragetNewThing() paraNewFlipService. @FlipBean é outra alternância que é mais útil quando combinada com outras. Vamos dar uma olhada nisso agora.

7. Combinando Alternadores

Combinamos alternâncias especificando mais de uma. Flips as avalia em sequência, com lógica implícita "AND". Portanto, todos eles devem ser verdadeiros para ativar o recurso.

Vamos combinar dois de nossos exemplos anteriores:

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

Usamos o novo serviço configurável.

8. Conclusão

Neste breve guia, criamos um serviço simples do Spring Boot e ativamos e desativamos as APIs usando as anotações do Flips. Vimos como os recursos são alternados usando informações de configuração e data / hora, e também como os recursos podem ser alternados trocando beans em tempo de execução.

Amostras de código, como sempre, podem ser encontradasover on GitHub.