代码经验---feign调用实现url和接口路径的动态配置化

前言:
在微服务盛行的今天,做接口开发请求第三方服务的接口,大概率会用feign做请求,而feign也是最常用的一种rpc框架;

这里主要是说明在进行feign请求的时候,第三方服务的url和接口也是可以通过读取配置文件的配置,来进行请求的;

至于为什么要把接口和url写在配置中呢,其实也是看需求了;
若是该接口是作为基础服务可能会请求多个第三方使用(我们就是不同分支的代码作为独立项目部署,请求不同的客户接口),不同客户的接口地址可能不同,此时就需要做成配置方式;
若是不常改动,其实也没必要做成配置了;

常用方式:
通常我们是这么请求第三方接口的:(用feign方式)


@FeignClient(name = "feignCustomerService", url = "${customer.url}",configuration = FeignClientConfig.class)
public interface FeignCustomerService {
    /**
     * 请求客户的接口
     */
    @RequestMapping(value = "order/update", method = RequestMethod.POST)
    @Headers(value = "Content-Type: application/json")
    OrderHttpResponse updateOrder(@RequestBody OrderUpdateDTO orderUpdateDTO);

}

说明:
请求客户的url是读取的配置文件中的值,
调用客户的具体的目标方法是:order/update 这个方法
我们配置文件(yml文件):

# 请求客户,客户的接口配置
customer:
  url: http://127.0.0.1:8888/
    

这样的话,最终请求客户这个接口的url就是:
http://127.0.0.1:8888/order/update

问题来了:
这整个url可以看成两部分,一部分是ip和端口,一部分是请求的路径
第一部分:[http://127.0.0.1:8888/]
第二部分:[order/update]

那其实上面我们已经把第一部分写到配置文件中了,第二部分还是写死在代码中,怎么实现第二部分也在配置中配置呢?

方式一:@Value(“”)

@Value(“”)
这种方式可以读取配置文件中的值,但是我们这里都是feign接口,接口中定义的变量仅可以为static final的,
说白了:就是要interface中的常量必须要初始化的,
这种是动态读取的,达不到我们的要求;

方式二:利用@PathVariable注解的特性;

利用@PathVariable注解的特性;

用于接收请求路径中占位符的值

@PathVariable(“xxx”)
通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中
如:
@RequestMapping(value=”user/{id}/{name}”)
请求路径:http://localhost:8080/hello/show/1/lisi

所以改造下我们的方法:


@FeignClient(name = "feignCustomerService", url = "${customer.url}",configuration = FeignClientConfig.class)
public interface FeignCustomerService {
    /**
     * 请求客户的接口
     */
    @RequestMapping(value = "{apiName}", method = RequestMethod.POST)
    @Headers(value = "Content-Type: application/json")
    OrderHttpResponse updateOrder(@PathVariable("apiName") String apiName, @RequestBody OrderUpdateDTO orderUpdateDTO);

}

然后在配置文件中增加:

# 请求客户,客户的接口配置
customer:
  url: http://127.0.0.1:8888/
  updateOrderApiName: order/update
  insertOrderApiName: order/insert

然后再增加一个配置类,用于读取该配置:

@Component
@ConfigurationProperties(prefix = "customer")
@Setter
public class FeignConsumerConfig {
	public String url;
	public String updateOrderApiName;
	public String insertOrderApiName;
}

然后就可以这样请求这个feign方法:

@Slf4j
@RestController
@RequestMapping(value = "")
public class TestController {

    @Autowired
    private FeignCustomerService feignCustomerService;
    
    @Autowired
    private FeignConsumerConfig feignConsumerConfig;

    
    @RequestMapping(value = "/testFeign", method = RequestMethod.POST)
    public void testFeign() {

        OrderUpdateDTO orderUpdateDTO = new OrderUpdateDTO();
        orderUpdateDTO.setOrderId(22222);
        orderUpdateDTO.setxxx(111111111);
        OrderHttpResponse orderHttpResponse = feignCustomerService.updateOrder(feignConsumerConfig.updateOrderApiName,orderUpdateDTO);
        log.info("orderHttpResponse :{}",JSONObject.toJSONString(orderHttpResponse));
    }
}

其实就是比之前的调用多了一个参数(不影响),而且这个参数会替换到url中去,变相的实现了可配置;
最终的url:
http://127.0.0.1:8888/order/update

缺点:
只是会多一个参数,我觉得不影响,客户那边接收业务参数的话,只需要接收orderUpdateDTO即可,因为我们的业务参数都是写在这个类的,对于客户和我们来说,不影响业务执行;

方式三:利用${} 方式(也是最简单的方式)

@FeignClient(name = "feignCustomerService", url = "${customer.url}",configuration = FeignClientConfig.class)
public interface FeignCustomerService {
    /**
     * 请求客户的接口
     */
    @RequestMapping(value = "${customer.updateOrderApiName}", method = RequestMethod.POST)
    @Headers(value = "Content-Type: application/json")
    OrderHttpResponse updateOrder(@RequestBody OrderUpdateDTO orderUpdateDTO);

}

只要配置文件配置了方法名,那我们这里直接用${}的方式读取就可以了,这也是最简单的一种方式;
建议使用这种;

说明:
看情况使用具体哪种方式:
方式二:适合通用的接口,具体调用哪个接口可能由url决定,也可能由请求体中某一个参数决定,
他们的相同点就是可以公用一个请求体的参数;

方式三:适合不同业务不同调用不同的方法,我们只需要写上这些方法,再请求不同的方法即可。

目前我想到的是这种方式,既可以把url可配置,请求路径也可实现可配置化,
如果有其它方式还请留言多交流;

你可能感兴趣的:(项目-代码-经验整理,feign,FeignClient,RequestMapping,feign动态配置url)