Introdução ao Spring Cloud OpenFeign

Introdução ao Spring Cloud OpenFeign

1. Visão geral

Neste tutorial, vamos descreverSpring Cloud OpenFeign - um cliente REST declarativo para aplicativos Spring Boot.

Feign torna a escrita de clientes de serviço da web mais fácil com suporte a anotações conectáveis, que inclui anotações Feign e anotações JAX-RS.

Além disso,Spring Cloud adiciona suporte paraSpring MVC annotationse para usar o mesmoHttpMessageConverters usado no Spring Web.

E, uma coisa ótima sobre o uso do Feign é que não precisamos escrever nenhum código para chamar o serviço, a não ser uma definição de interface.

2. Dependências

Primeiro, começaremos criando um projeto da web Spring Boot e adicionando a dependênciaspring-cloud-starter-openfeign ao nosso arquivopom.xml:


    org.springframework.cloud
    spring-cloud-starter-openfeign

Além disso, precisaremos adicionar ospring-cloud-dependencies:

 
     
         
            org.springframework.cloud
            spring-cloud-dependencies
            ${spring-cloud.version}
            pom
            import
        
    

Podemos encontrar as versões mais recentes despring-cloud-starter-openfeignespring-cloud-dependencies no Maven Central.

3. Cliente fingir

Em seguida, precisamos adicionar@EnableFeignClients à nossa classe principal:

@SpringBootApplication
@EnableFeignClients
public class ExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }
}

Com esta anotação, habilitamos a varredura de componentes para interfaces que declaram serem clientes Feign.

Então,we declare a Feign client using the @FeignClient annotation:

@FeignClient(value = "jplaceholder", url = "https://jsonplaceholder.typicode.com/")
public interface JSONPlaceHolderClient {

    @RequestMapping(method = RequestMethod.GET, value = "/posts")
    List getPosts();

    @RequestMapping(method = RequestMethod.GET, value = "/posts/{postId}", produces = "application/json")
    Post getPostById(@PathVariable("postId") Long postId);
}

Neste exemplo, configuramos um cliente para lerJSONPlaceHolder APIs.

O argumentovalue passado na nota sanitária@FeignClient é um nome de cliente arbitrário obrigatório, enquanto com o argumentourl, especificamos a URL base da API.

Além disso, como essa interface é um cliente Feign, podemos usar as anotações da Web Spring para declarar as APIs às quais queremos acessar.

4. Configuração

Agora, é muito importante entender queeach Feign client is composed of a set of customizable components.

Spring Cloud cria um novo conjunto padrão sob demanda para cada cliente nomeado usando a classeFeignClientsConfiguration que podemos personalizar conforme explicado na próxima seção.

A classe acima contém estes beans:

  • Decodificador -ResponseEntityDecoder, que envolveSpringDecoder, used para decodificar oResponse

  • Codificador -SpringEncoder, usado para codificar oRequestBody

  • Logger -Slf4jLogger é o logger padrão usado pelo Feign

  • Contrato -SpringMvcContract, que fornece processamento de anotação

  • Feign-Builder -HystrixFeign.Builder usado para construir os componentes

  • Cliente -LoadBalancerFeignClient ou cliente Feign padrão

4.1. Configuração Custom Beans

In the event that we want to customize one or more of these beans, podemos substituí-los usando uma classe@Configuration, que então adicionamos à anotaçãoFeignClient:

@FeignClient(value = "jplaceholder",
  url = "https://jsonplaceholder.typicode.com/",
  configuration = MyClientConfiguration.class)
@Configuration
public class MyClientConfiguration {

    @Bean
    public OkHttpClient client() {
        return new OkHttpClient();
    }
}

Neste exemplo, dizemos ao Feign para usarOkHttpClient em vez do padrão para suportar HTTP / 2.

O Feign oferece suporte a vários clientes para diferentes casos de uso, incluindoApacheHttpClient, que envia mais cabeçalhos com a solicitação - por exemplo,Content-Length, que alguns servidores esperam.

Para usar esses clientes, não se esqueça de adicionar as dependências necessárias ao nosso arquivopom.xml, por exemplo:


    io.github.openfeign
    feign-okhttp



    io.github.openfeign
    feign-httpclient

Podemos encontrar as versões mais recentes defeign-okhttpefeign-httpclient no Maven Central.

4.2. Configuração usando propriedades

Em vez de usar uma classe@Configuration,we can use application properties to configure Feign clients, conforme mostrado neste exemploapplication.yaml:

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic

Com essa configuração, estamos definindo os tempos limite para 5 segundos e o nível do logger parabasic para cada cliente declarado no aplicativo.

Finalmente, podemos criar a configuração comdefault como o nome do cliente para configurar todos os objetos@FeignClient, ou podemos declarar o nome do cliente fingido para uma configuração:

feign:
  client:
    config:
      jplaceholder:

No caso de termos@Configuration bean e propriedades de configuração, as propriedades de configuração substituirão os valores@Configuration.

5. Interceptores

Adicionar interceptores é outro recurso útil fornecido pelo Feign.

Os interceptores podem executar uma variedade de tarefas implícitas, da autenticação ao log, para cada solicitação / resposta HTTP.

Portanto, no snippet abaixo, vamos declarar um interceptor de solicitação que adiciona autenticação básica a cada solicitação:

@Bean
public RequestInterceptor requestInterceptor() {
  return requestTemplate -> {
      requestTemplate.header("user", username);
      requestTemplate.header("password", password);
      requestTemplate.header("Accept", ContentType.APPLICATION_JSON.getMimeType());
  };
}

Além disso, para adicionar o interceptor à cadeia de solicitação, precisamos apenas adicionar este bean à nossa classe@Configuration ou, como vimos anteriormente, declará-lo no arquivo de propriedades:

feign:
  client:
    config:
      default:
        requestInterceptors:
          com.example.cloud.openfeign.JSONPlaceHolderInterceptor

6. Suporte Hystrix

Feign é compatível comHystrix, então, se o habilitamos,we can implement the fallback pattern.

Com o padrão de fallback, quando uma chamada de serviço remoto falha, em vez de gerar uma exceção, o consumidor do serviço executa um caminho de código alternativo para tentar executar a ação por outros meios.

Para atingir o objetivo, precisamos habilitar Hystrix adicionandofeign.hystrix.enabled=true no arquivo de propriedades.

Isso nos permite implementar métodos de fallback chamados quando o serviço falha:

@Component
public class JSONPlaceHolderFallback implements JSONPlaceHolderClient {

    @Override
    public List getPosts() {
        return Collections.emptyList();
    }

    @Override
    public Post getPostById(Long postId) {
        return null;
    }
}

Para informar ao Feign que os métodos de fallback foram fornecidos, também precisamos definir nossa classe de fallback na anotação@FeignClient:

@FeignClient(value = "jplaceholder",
  url = "https://jsonplaceholder.typicode.com/",
  fallback = JSONPlaceHolderFallback.class)
public interface JSONPlaceHolderClient {
    // APIs
}

7. Exploração madeireira

Para cada cliente Feign, um criador de logs é criado por padrão.

Para habilitar o registro, devemos declará-lo no arquivoapplication.properties usando o nome do pacote das interfaces do cliente:

logging.level.com.example.cloud.openfeign.client: DEBUG

Ou, se quisermos habilitar o log apenas para um cliente em particular em um pacote, podemos usar o nome completo da classe:

logging.level.com.example.cloud.openfeign.client.JSONPlaceHolderClient: DEBUG

Observe que o log de Feign responde apenas ao nívelDEBUG.

OLogger.Level que podemos configurar por cliente indica quanto registrar:

@Configuration
public class ClientConfiguration {

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.BASIC;
    }
}

Existem quatro níveis de registro para você escolher:

  • NONE - sem registro, que é o padrão

  • BASIC - registra apenas o método de solicitação, URL e status de resposta

  • HEADERS - registra as informações básicas junto com os cabeçalhos de solicitação e resposta

  • FULL - registra o corpo, cabeçalhos e metadados para solicitação e resposta

8. Manipulação de erros

O manipulador de erros padrão de Feign,ErrorDecoder.default, sempre lança umFeignException.

Agora, esse comportamento nem sempre é o mais útil. Então,to customize the Exception thrown, we can use a CustomErrorDecoder:

public class CustomErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {

        switch (response.status()){
            case 400:
                return new BadRequestException();
            case 404:
                return new NotFoundException();
            default:
                return new Exception("Generic error");
        }
    }
}

Então, como fizemos anteriormente, temos que substituir oErrorDecoder padrão adicionando um bean à classe@Configuration:

@Configuration
public class ClientConfiguration {

    @Bean
    public ErrorDecoder errorDecoder() {
        return new CustomErrorDecoder();
    }
}

9. Conclusão

Neste artigo, discutimos o Spring Cloud OpenFeign e sua implementação em um aplicativo de amostra simples.

Além disso, vimos como configurar um cliente, como adicionar interceptores às nossas solicitações e como lidar com erros usandoHystrixeErrorDecoder.

Como de costume, todos os exemplos de código mostrados neste tutorial estão disponíveisover on GitHub.