Spring Cloud OpenFeign Custom#
Why Do We Need To Custom OpenFeign?#
- So If you had take an example with Spring Cloud OpenFeign Basic so you can handle business requirements that need to call to another applications. However for specific cases, you had to create your own configurations. So let's imagine that you have a spring boot application and there is a business requirement that requires you to export an api. In which, this api should response data from 2 servers based on the ISO country code because one server is deployed at VietNam and the other one is deployed at Singapore.
- So some people can say that, they can create 2
OpenFeign
interfaces and useif else
orswitch case
for the ISO country code to get the suitableOpenFeign
. Yes, actually they can handle this case like that but if later we have 10 or 20 servers deployed at 10 or 20 countries, so you have to create 10 or 20OpenFeign
interfaces and useif else
orswitch case
to support these countries codes? - Actually, we just need to configure the
OpenFeign
a little bit and this business requirement can be solved and we also don't worry about extend supports for 10 or 20 servers deployed at 10 or 20 countries. -So, let's take an example in the following steps.
Dependencies#
- Dependency for Spring Cloud
pom.xml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
- Then you can add this dependency below for Spring Cloud OpenFeign.
pom.xml | |
---|---|
1 2 3 4 5 |
|
- Because we will configure Spring Cloud OpenFeign more to handle our business, so we have to add some more dependencies as below.
pom.xml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Configuration#
- Assume that VietNam and Singapore servers export the api
GET blog/posts/{id}
. So, we have to create an adapter interface for this api target as below.
AdapterServiceApi.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
- Then, create a configuration class and use
Feign.builder()
to configureFeign
for the adapter interface as below
FeignClientAdapterBuilder.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
- So, the default
Feign
configurations inSpring Cloud OpenFeign
will look like in the table below.
BeanType | BeanName | ClassName |
---|---|---|
Decoder | feignDecoder | SpringDecoder |
Encoder | feignEncoder | SpringEncoder |
Logger | feignLogger | Slf4jLogger |
MicrometerCapability | micrometerCapability | If feign-micrometer is on the classpath and MeterRegistry is available |
CachingCapability | cachingCapability | If @EnableCaching annotation is used. Can be disabled via feign.cache.enabled. |
Contract | feignContract | SpringMvcContract |
Feign.Builder | feignBuilder | FeignCircuitBreaker.Builder |
Client | feignClient | If Spring Cloud LoadBalancer is on the classpath, FeignBlockingLoadBalancerClient is used. If none of them is on the classpath, the default feign client is used. |
- In this example, we will change some configurations as in the following table.
BeanType | BeanName | ClassName |
---|---|---|
Decoder | gsonDecoder | SpringDecoder |
Encoder | gsonDecoder | SpringEncoder |
Logger | slf4jLogger | Slf4jLogger |
Contract | springMvcContract | SpringMvcContract |
Feign.Builder | feignBuilder | Feign.Builder |
Client | okHttpClient | OkHttpClient |
- As you can see in the target configuration, the url will be dynamic set base on the input
code
of method. In this example, it will be the2 ISO countryCode
. So we need to add the target urls intoapplication.yml
as below.
application.yml | |
---|---|
1 2 3 4 5 6 7 8 |
|
- So with the country code is
vn
orsg
, It will call to the url respectively. Then if in future, there are 10 or 20 more servers with 10 or 20 new country codes, we just need to add them in thisapplication.yml
and restart our Spring Boot application.
Service#
- Now we can use this
FeignClientAdapterBuilder
in any Service class by@Autowired
. Let’s create a service and put codes as below
PostService.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Controller#
- Finally, create a simple REST controller with an api which will call the Service above.
ApiController.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|