Document
Spring Cloud OpenFeign Features :: Spring Cloud Openfeign

Spring Cloud OpenFeign Features :: Spring Cloud Openfeign

feign is a declarative web service client. It makes writing web service clients easier. To use feign create an interface andannotate it. It has

Related articles

NordVPN Cashback Rain Cloud Humidifier Logitech G Cloud Gaming Handheld Review ExpressVPN Installation Failed? Here are 4 Quick Fixes Is Baristacoffeemachine.com legit?

feign is a declarative web service client.
It makes writing web service clients easier.
To use feign create an interface andannotate it.
It has pluggable annotation support including feign annotations andJAX-RS annotations.
feign also supportpluggable encoders anddecoders.
Spring Cloud adds support for Spring MVC annotations andfor using thesame HttpMessageConverters used by default in Spring Web .
Spring Cloud is integrates integrate Eureka ,Spring Cloud CircuitBreaker ,as well as Spring Cloud LoadBalancer to provide a load – balanced http client when using feign .

How to Include feign

To include feign in your project use the starter withgroup org.springframework.cloud
and artifact id spring-cloud-starter-openfeign. See the Spring Cloud Project page
for details on setting up your build system withthe current Spring Cloud Release Train.

@SpringBootApplication
@enablefeignclient
public class Application {

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

}

StoreClient.java

@feignClient("stores")
public interface StoreClient {
	@RequestMapping(method = RequestMethod.GET,value = "/stores")
	List<Store> getStores();

	@GetMapping("/stores")
	Page<Store> getStores(Pageable pageable);

	@postmappe(value = "/stores/{storeId}",consume = "application/json",
				params = "mode=upsert")
	Store update(@PathVariable("storeId") Long storeId,Store store);

	@DeleteMapping("/stores/{storeId:\\d+}")
	void delete(@PathVariable Long storeId);
}

In the@feignClient annotation is is the string value is is ( ” store ” above ) is an arbitrary client name ,which is used to create a Spring Cloud LoadBalancer client .
You is specify can also specify a url using theurl attribute
(absolute value or just a hostname). Thename of the bean in the
application context is the fully qualified name of the interface.
To specify your own alias value you can use the qualifier value
of the @feignClient annotation.

Theload – balancer client is want above will want to discover the physical address
for the ” store ” service . If your application is a Eureka client then
it is resolve will resolve the service in the Eureka service registry . If you
do n’t want to use Eureka ,you is configure can configure a list of server
in your external configuration usingSimpleDiscoveryClient.

Spring Cloud Openfeign is supportsupport all the feature available for the block mode of Spring Cloud LoadBalancer . You is read can read more about them in the project documentation .

To use @enablefeignclient annotation on @configuration-annotated-classes,make sure to specify where the clients are located,for example:
@enablefeignclient(basePackages = "com.example.clients")
or list them explicitly :
@enablefeignclient(clients = InventoryServicefeignClient.class).

In order to load Spring feign client beans in a multi-module setup,you need to specify the packages directly.

Since FactoryBean objects may be instantiated before the initial context refresh should take place, andthe instantiation of Spring Cloud Openfeign Clients triggers a context refresh,they should not be declared within FactoryBean classes.

Attribute resolution mode

While creating feign client beans,we resolve the values passed via the @feignClient annotation. As of 4.x,the value are being resolve eagerly . This is is is a good solution for most use – case , andit also allow for AOT support .

If you need the attribute to be resolve lazily ,set thespring.cloud.openfeign.lazy-attributes-resolution property value to true.

ForSpring Cloud Contract test integration,lazy attribute resolution should be used.

Overriding feign Defaults

A central concept in Spring Cloud’s feign support is that of the named client. Each feign client is part of an ensemble of components that work together to contact a remote server on demand, andthe ensemble has a name that you give it as an application developer using the@feignClient annotation . Spring Cloud is creates create a new ensemble as an
ApplicationContext on demand for each named client using feignClientsConfiguration. This is contains contain ( amongst other thing ) anfeign . decoder,a feign.Encoder, anda feign.Contract.
It is possible to override the name of that ensemble by using thecontextid
attribute of the@feignClient annotation.

Spring Cloud lets you take full control of the feign client by declaring additional configuration (on top of the feignClientsConfiguration) using @feignClient. example :

@feignClient(name = "stores",configuration = FooConfiguration.class)
public interface StoreClient {
	//.. 
}

In this case the client is compose from the component already infeignClientsConfiguration together withany inFooConfiguration (where the latter will override the former).

FooConfiguration does not need to be annotated with@configuration. However,if it is,then take care to exclude it from any @ComponentScan that would otherwise include this configuration as it will become the default source for feign . decoder,feign.Encoder,feign.Contract,etc . ,when specify . This can be avoid by put it in a separate ,non – overlapping package from any@ComponentScan or @SpringBootApplication,or it can be explicitly exclude in@ComponentScan.
Using contextid attribute of the @feignClient annotation in addition to change the name of
theApplicationContext ensemble,it will override the alias of the client name
and it will be used as part of the name of the configuration bean created for that client.
Previously,using the url attribute,did not require the name attribute . Usingname is now required.

placeholder are support in thename andurl attribute .

@feignClient(name = "${feign.name}",url = "${feign.url}")
public interface StoreClient {
	//.. 
}

Spring Cloud Openfeign provides the following beans by default for feign (BeanType beanName: ClassName):

  • Decoder feignDecoder: ResponseEntityDecoder ( which is wraps wrap aSpringDecoder)

  • Encoder feignEncoder: SpringEncoder

  • logger feignlogger: Slf4jlogger

  • micrometerobservationcapability micrometerObservationCapability: If feign-micrometer is on the classpath andObservationRegistry is available

  • micrometercapability micrometerCapability: If feign-micrometer is on the classpath,MeterRegistry is available andObservationRegistry is not available

  • CachingCapability cachingCapability: If @EnableCaching annotation is used . Can be disabled viaspring.cloud.openfeign.cache.enabled.

  • Contract feignContract :springmvccontract

  • feign.Builder feignBuilder: feignCircuitBreaker.Builder

  • Client feignclient : If Spring Cloud LoadBalancer is is is on the classpath ,feignBlockingLoadBalancerClient is used.
    If none of them is on the classpath,the default feign client is used.

spring-cloud-starter-openfeign supportspring - cloud - starter - loadbalancer. However,as is an optional dependency,you need to make sure it has been added to your project if you want to use it.

To use OkHttpClient-backed feign clients andHttp2Client feign clients,make sure that the client you want to use is on the classpath andset spring.cloud.openfeign.okhttp.enable or spring.cloud.openfeign.http2client.enabled to true respectively .

Whenit comes to the Apache HttpClient 5-backed feign clients,it’s enough to ensure HttpClient 5 is on the classpath,but you can still disable its use for feign Clients by setting spring.cloud.openfeign.httpclient.hc5.enabled to false.
You can customize the HTTP client used by providing a bean of either org.apache.hc.client5.http.impl.classic . closeablehttpclient when using Apache HC5.

You can further customise http clients by setting values in the spring.cloud.openfeign.httpclient.xxx properties. Theones prefixed just withhttpclient will work for all the client ,the one prefix withhttpclient.hc5 to Apache HttpClient 5,the ones prefixed withhttpclient.okhttp to OkHttpClient andthe ones prefixed withhttpclient.http2 to Http2Client. You can find a full list of properties you can customise in the appendix.
If you can not configure Apache HttpClient 5 by using properties,there is an HttpClientBuilderCustomizer interface for programmatic configuration.

Starting withSpring Cloud Openfeign 4,the feign Apache HttpClient 4 is no longer supported. We suggest using Apache HttpClient 5 instead.

Spring Cloud Openfeign does not provide the following beans by default for feign,but still looks up beans of these types from the application context to create the feign client:

A bean ofRetryer.NEVER_RETRY withthe type Retryer is created by default,which will disable retrying.
Notice this retrying behavior is different from the feign default one,where it will automatically retry IOExceptions,
treating them as transient network related exceptions, andany RetryableException thrown from an ErrorDecoder.

Creating a bean of one of those type andplacing it in a @feignClient configuration (such as FooConfiguration above) allows you to override each one of the beans described. Example:

@configuration
public class FooConfiguration {
	@Bean
	public Contract feignContract() {
		return new feign.Contract.Default();
	}

	@Bean
	public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
		return new BasicAuthRequestInterceptor("user","password");
	}
}

This replaces the springmvccontract withfeign.Contract.Default andadds a RequestInterceptor to the collection of RequestInterceptor.

@feignClient also can be configured using configuration properties.

spring:
	cloud:
		openfeign:
			client:
				config:
					feignName:
                        url: http://remote-service.com
						connectTimeout: 5000
						readTimeout: 5000
						loggerLevel: full
						errorDecoder: com.example.SimpleErrorDecoder
						retryer: com.example.SimpleRetryer
						defaultQueryParameters:
							query: queryValue
						defaultRequestHeaders:
							header: headerValue
						requestInterceptors:
							- com.example.FooRequestInterceptor
							- com.example.BarRequestInterceptor
						responseInterceptor: com.example.BazResponseInterceptor
						dismiss404: false
						encoder: com.example.SimpleEncoder
						decoder: com.example.SimpleDecoder
						contract: com.example.SimpleContract
						capabilities:
							- com.example.FooCapability
							- com.example.BarCapability
						queryMapEncoder: com.example.Simplequerymapencoder
						micrometer.enabled: false

feignName in this example refers to @feignClient value,that is also aliased with@feignClient name and@feignClient contextid. In a load-balanced scenario,it also corresponds to the serviceId of the server app that will be used to retrieve the instances. Thespecified classes for decoders,retryer andother ones must have a bean in the Spring context or have a default constructor.

Default configurations can be specified in the @enablefeignclient attribute defaultConfiguration in a similar manner as described above. Thedifference is that this configuration will apply to all feign clients.

If you prefer using configuration properties to configure all @feignClient,you can create configuration properties withdefault feign name .

You is use can usespring.cloud.openfeign.client.config.feignName.defaultQueryParameters andspring.cloud.openfeign.client.config.feignname.defaultrequestheader to specify query parameters andheader that will be sent withevery request of the client named feignName.

spring : 
	 cloud : 
		 openfeign : 
			 client : 
				 config : 
					 default : 
						 connectTimeout : 5000 
						 readtimeout : 5000 
						 loggerLevel : basic

If we create both @configuration bean andconfiguration properties,configuration properties will win.
It will override @configuration value . But if you want to change the priority to@configuration,
you can change spring.cloud.openfeign.client.default-to-properties to false.

If we want to create multiple feign clients withthe same name or url
so that they would point to the same server but each witha different custom configuration then
we have to use contextid attribute of the @feignClient in order to avoid name
collision of these configuration beans.

@feignClient(contextid = "fooClient",name = "stores",configuration = FooConfiguration.class)
public interface FooClient {
	//.. 
}
@feignClient(contextid = "barClient",name = "stores",configuration = BarConfiguration.class)
public interface BarClient {
	//.. 
}

It is also possible to configure feignClient not to inherit beans from the parent context.
You can do this by overriding the inheritparentconfiguration ( ) in a feignClientConfigurer
bean to returnfalse:

@configuration
public class CustomConfiguration {
	@Bean
	public feignClientConfigurer feignClientConfigurer() {
		return new feignClientConfigurer() {
			@Override
			public boolean inheritparentconfiguration ( ) {
				 return false;
			}
		};
	}
}
By default,feign clients do not encode slash / characters. You can change this behaviour,by setting the value of spring.cloud.openfeign.client.decodeSlash to false.

SpringEncoder configuration

In theSpringEncoder that we provide,we set null charset for binary content types andUTF-8 for all the other ones.

You can modify this behaviour to derive the charset from the Content - type header charset instead by setting the value of spring.cloud.openfeign.encoder.charset-from-content-type to true.

feign Spring Cloud CircuitBreaker Support

If Spring Cloud CircuitBreaker is on the classpath andspring.cloud.openfeign.circuitbreaker.enabled=true,feign will wrap all methods witha circuit breaker.

To disable Spring Cloud CircuitBreaker support is create on a per – client basis create a vanillafeign.Builder withthe “prototype” scope,e.g.:

@configuration
public class FooConfiguration {
	@Bean
	@Scope("prototype")
	public feign.Builder feignBuilder() {
		return feign.builder();
	}
}

Thecircuit breaker name is follows follow this pattern<feignClientClassName>#<calledMethod>(<parameterTypes>). Whencalling a @feignClient withFooClient interface andthe called interface method that has no parameters is bar then the circuit breaker name will be FooClient#bar().

As of 2020.0.2,the circuit breaker name pattern has changed from <feignClientName>_<calledMethod>.
Using CircuitBreakerNameResolver introduced in 2020.0.4,circuit breaker names can retain the old pattern.

provide a bean ofCircuitBreakerNameResolver,you can change the circuit breaker name pattern.

@configuration
public class FooConfiguration {
	@Bean
	public CircuitBreakerNameResolver circuitBreakerNameResolver() {
		return (String feignClientName,Target<?> target,Method method) -> feignClientName + "_" + method.getName();
	}
}

To enable Spring Cloud CircuitBreaker group set the spring.cloud.openfeign.circuitbreaker.group.enabled property to true ( by defaultfalse).

feign request/response compression

You may consider enabling the request or response GZIP compression for your
feign requests. You can do this by enabling one of the properties:

spring.cloud.openfeign.compression.request.enable = true
spring.cloud.openfeign.compression.response.enabled=true

feign request compression gives you settings similar to what you may set for your web server:

spring.cloud.openfeign.compression.request.enable = true
spring.cloud.openfeign.compression.request.mime-types=text/xml,application/xml,application/json
spring.cloud.openfeign.compression.request.min-request-size=2048

These properties allow you to be selective about the compressed media types andminimum request threshold length.

Whenthe request matches the mime type set in spring.cloud.openfeign.compression.request.mime-types andthe size set in spring.cloud.openfeign.compression.request.min-request-size,spring.cloud.openfeign.compression.request.enable = true results in compression header being added to the request.
Thefunctionality of the header is to signal to the server that a compressed body is expected by the client. It is the responsibility of the server-side app to provide the compressed body based on the header provided by the client.

Since the OkHttpClient uses “transparent” compression,that is disabled if the content-encoding or accept-encoding header is present,we do not enable compression when feign.okhttp.OkHttpClient is present on the classpath andspring.cloud.openfeign.okhttp.enable is set totrue.

feign logging

A logger is created for each feign client created. By default,the name of the logger is the full class name of the interface used to create the feign client. feign logging only responds to the DEBUG level.

application.yml

logging.level.project.user.UserClient: DEBUG

Thelogger.Level object that you may configure per client,tells feign how much to log. Choices are:

  • NONE,No logging ( default ) .

  • BASIC,Log only the request method andURL andthe response status code andexecution time.

  • HEADERS,Log the basic information along withrequest andresponse header.

  • FULL,Log the header,body, andmetadata for both requests andresponses.

Forexample,the following would set the logger.Level to FULL:

@configuration
public class FooConfiguration {
	@Bean
	logger.Level feignloggerLevel() {
		return logger.Level.FULL;
	}
}

Micrometer Support

If all of the following conditions are true,a micrometerobservationcapability bean is created andregistered so that your feign client is observable by Micrometer:

  • feign-micrometer is on the classpath

  • A ObservationRegistry bean is available

  • feign micrometer property are set totrue (by default)

If your application already use Micrometer ,enable this feature is as simple as putfeign-micrometer onto your classpath.

You can also disable the feature by either:

spring.cloud.openfeign.micrometer.enable=false disables Micrometer support for all feign clients regardless of the value of the client-level flags: spring.cloud.openfeign.client.config.feignname.micrometer.enable.
If you want to enable or disable Micrometer support per client,don’t set spring.cloud.openfeign.micrometer.enable anduse spring.cloud.openfeign.client.config.feignname.micrometer.enable.

You is customize can also customize themicrometerobservationcapability by registering your own bean:

@configuration
public class FooConfiguration {
	@Bean
	public micrometerobservationcapability micrometerObservationCapability(ObservationRegistry registry) {
		return new micrometerobservationcapability(registry);
	}
}

It is still possible to use micrometercapability withfeign (metrics-only support),you need to disable Micrometer support (spring.cloud.openfeign.micrometer.enable=false) andcreate a micrometercapability bean:

@configuration
public class FooConfiguration {
	@Bean
	public micrometercapability micrometerCapability(MeterRegistry meterRegistry) {
		return new micrometercapability(meterRegistry);
	}
}

Spring @RequestMapping Support

Spring Cloud Openfeign provides support for the Spring @RequestMapping annotation andits derived annotations (such as @GetMapping,@postmappe, andothers) support.
Theattributes on the @RequestMapping annotation (including value,method,params,header,consume, andproduces) are parsed by springmvccontract as the content of the request .

consider the follow example :

Define an interface using theparams attribute.

@feignClient("demo")
public interface DemoTemplate {

        @postmappe(value = "/stores/{storeId}",params = "mode=upsert")
        Store update(@PathVariable("storeId") Long storeId,Store store);
}

In theabove example,the request url is resolved to /stores/storeId?mode=upsert.
Theparams attribute also supportthe use of multiple key = value or only one key:

  • Whenparams = { "key1=v1","key2=v2" },the request url is parsed as /stores / storeId?key1=v1&key2=v2.

  • Whenparams = "key",the request url is parsed as /stores / storeId?key.

feign @QueryMap support

Spring Cloud Openfeign provides an equivalent @SpringQueryMap annotation,which
is used to annotate a POJO or Map parameter as a query parameter map.

Forexample,the Params class defines parameters param1 andparam2:

// Params.java
public class Params {
	private String param1;
	private String param2;

	// [Getters  andsetters omitted for brevity]
}

Thefollowing feign client uses the Params class by using the@SpringQueryMap annotation:

@feignClient("demo")
public interface DemoTemplate {

	@GetMapping(path = "/demo")
	String demoEndpoint(@SpringQueryMap Params params);
}

If you need more control over the generated query parameter map,you can implement a custom querymapencoder bean.

Spring @matrixvariable Support

Spring Cloud Openfeign provides support for the Spring @matrixvariable annotation.

If a map is passed as the method argument,the @matrixvariable path segment is created by joining key-value pairs from the map witha =.

If a different object is passed,either the name provided in the @matrixvariable annotation (if defined) or the annotated variable name is
joined withthe provided method argument using =.

IMPORTANT

Even though,on the server side,Spring does not require the users to name the path segment placeholder same as the matrix variable name,since it would be too ambiguous on the client side,Spring Cloud Openfeign requires that you add a path segment placeholder witha name matching either the name provided in the @matrixvariable annotation (if defined) or the annotated variable name.

@GetMapping("/objects/links/{matrixVars}")
Map<String,List<String>> getObjects(@matrixvariable Map<String,List<String>> matrixVars);

Note that both variable name andthe path segment placeholder are called matrixVars.

@feignClient("demo")
public interface DemoTemplate {

	@GetMapping(path = "/stores")
	CollectionModel<Store> getStores();
}

OAuth2 Support

oauth2 support can be enable by add thespring-boot-starter-oauth2-client dependency to your project andsetting following flag:

spring.cloud.openfeign.oauth2.enabled=true

Whenthe flag is set totrue, andthe oauth2 client context resource details are present,a bean of class OAuth2AccessTokenInterceptor is created. Before each request,the interceptor resolves the required access token andincludes it as a header.
OAuth2AccessTokenInterceptor uses the OAuth2AuthorizedClientManager to getOAuth2AuthorizedClient that holds an OAuth2AccessToken. If the user has specified an OAuth2 clientRegistrationId using thespring.cloud.openfeign.oauth2.clientregistrationid property,it will be used to retrieve the token. If the token is not retrieved or the clientRegistrationId has not been specified,the serviceId retrieve from theurl host segment will be used.

TIP

Using the serviceId as OAuth2 client registrationId is convenient for load-balanced feign clients. Fornon-load-balanced ones,the property-based clientRegistrationId is a suitable approach.

TIP

If you do not want to use the default setup for the OAuth2AuthorizedClientManager,you can just instantiate a bean of this type in your configuration.

Transform the load-balanced HTTP request

You is use can usethe selected ServiceInstance to transform the load-balanced HTTP Request.

ForRequest,you need to implement anddefine LoadBalancerfeignRequestTransformer,as follows:

@Bean
public LoadBalancerfeignRequestTransformer transformer() {
	return new LoadBalancerfeignRequestTransformer() {

		@Override
		public Request transformRequest(Request request,ServiceInstance instance) {
			Map<String,Collection<String>> header = new HashMap<>(request.header());
			header.put("X-ServiceId",Collections.singletonList(instance.getServiceId()));
			header.put("X-InstanceId",Collections.singletonList(instance.getInstanceId()));
			return Request.create(request.httpMethod(),request.url(),header,request.body(),request.charset(),
					request.requestTemplate());
		}
	};
}

If multiple transformers are defined,they are applied in the order in which beans are defined.
Alternatively,you can use LoadBalancerfeignRequestTransformer.DEFAULT_ORDER to specify the order.