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
OpenFeigninterfaces and useif elseorswitch casefor 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 20OpenFeigninterfaces and useif elseorswitch caseto support these countries codes? - Actually, we just need to configure the
OpenFeigna 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 configureFeignfor 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
Feignconfigurations inSpring Cloud OpenFeignwill 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
codeof method. In this example, it will be the2 ISO countryCode. So we need to add the target urls intoapplication.ymlas below.
| application.yml | |
|---|---|
1 2 3 4 5 6 7 8 | |
- So with the country code is
vnorsg, 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.ymland restart our Spring Boot application.
Service#
- Now we can use this
FeignClientAdapterBuilderin 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 | |