Implementing a Dynamic Feign Client for Simplified Microservice Calls
This article explains how to create a reusable dynamic Feign client in Java, replacing multiple static Feign interfaces with a generic service that can invoke any microservice endpoint via configurable URLs, and provides full code examples and usage instructions.
Feign simplifies HTTP calls between microservices in Java, allowing developers to avoid writing low‑level HTTP code.
Typically each microservice has its own Feign client interface, which can become repetitive and cumbersome.
To make Feign usage dynamic, the article first shows the usual static approach with separate client interfaces:
@FeignClient(name = "system")
public interface SystemClient {
@GetMapping("/system/test1")
JsonResult test1(String test1);
@GetMapping("/system/test2")
JsonResult test2(String test2);
// ...
}
@FeignClient(name = "user")
public interface UserClient {
@GetMapping("/user/test1")
JsonResult test1(String test1);
@GetMapping("/user/test2")
JsonResult test2(String test2);
// ...
}Instead of defining many such interfaces, a generic DynamicService interface is introduced, providing a universal POST and GET method that accept the target URL and parameters.
public interface DynamicService {
@PostMapping("{url}")
Object executePostApi(@PathVariable("url") String url, @RequestBody Object params);
@GetMapping("{url}")
Object executeGetApi(@PathVariable("url") String url, @SpringQueryMap Object params);
}A DynamicClient component uses a DynamicFeignClientFactory to obtain a Feign client for a specified service name and then delegates the call to the generic methods.
@Component
public class DynamicClient {
@Autowired
private DynamicFeignClientFactory
dynamicFeignClientFactory;
public Object executePostApi(String feignName, String url, Object params) {
DynamicService dynamicService = dynamicFeignClientFactory.getFeignClient(DynamicService.class, feignName);
return dynamicService.executePostApi(url, params);
}
public Object executeGetApi(String feignName, String url, Object params) {
DynamicService dynamicService = dynamicFeignClientFactory.getFeignClient(DynamicService.class, feignName);
return dynamicService.executeGetApi(url, params);
}
}The factory class builds Feign clients at runtime using Spring’s FeignClientBuilder .
@Component
public class DynamicFeignClientFactory
{
private FeignClientBuilder feignClientBuilder;
public DynamicFeignClientFactory(ApplicationContext appContext) {
this.feignClientBuilder = new FeignClientBuilder(appContext);
}
public T getFeignClient(final Class
type, String serviceId) {
return this.feignClientBuilder.forType(type, serviceId).build();
}
}Usage is straightforward: retrieve the DynamicClient bean from the Spring context and call the desired method, passing the target service name, endpoint URL, and parameters.
DynamicClient dynamicClient = SpringUtil.getBean(DynamicClient.class);
Object result = dynamicClient.executePostApi(
"system",
"/system/test",
new HashMap<>());
System.out.println("==========>" + JSONObject.toJSONString(result));This approach provides a universal, reusable Feign client that can call any microservice endpoint without writing separate interfaces, greatly simplifying backend development.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.