feign
feign copied to clipboard
Support Dynamic Targets
I am writting a RequestInterceptor, need to know current "Target" so that I can revise the url of the RequestTemplate. While, I found the RequestTemplate.target is still null when it come into RequestInterceptor.apply method. Suggest to put the "target" value before invoke the RequestInterceptors, and provide a getter of RequestTemplate.target.
So my suggested code illustrate:
In RequestTemplate, add:
public String target() {
return target;
}
Then, the most important thing is that the target instance must not be null in RequestInterceptor.apply() method, so in SynchronousMethodHandler, add a line:
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
**template.target(this.target.name());**
Then in my interceptor:
@Bean
public RequestInterceptor cloudContextInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
String target = template.target();
if (target.contains("$CLUSTER_ID")) {
target = target.replace("$CLUSTER_ID", getClusterId(template));
template.target(target);
}
This is not really something that RequestInterceptor
is meant for. The Target
is immutable once created. Can you please explain what your intention is?
If you want to do dynamic host resolution, I suggest that you look into something like Ribbon or an alternative that can do that for you. Another option is to use our Request URI override support here:
https://github.com/OpenFeign/feign#interface-annotations
This is not really something that
RequestInterceptor
is meant for. TheTarget
is immutable once created. Can you please explain what your intention is?If you want to do dynamic host resolution, I suggest that you look into something like Ribbon or an alternative that can do that for you. Another option is to use our Request URI override support here:
https://github.com/OpenFeign/feign#interface-annotations
Our project is a very large application, need to divide a service to several cluster. e.g. CustomerService needs to be separated to CustomerService001, CustomerService002... Then we need will dispatch requests to different cluster according the customer number scope in RequestInterceptor. e.g. customer number from 0 to 1,000,000 will dispatch to CustomerService001, 1,000,001 to 2,000,000 dispatch to CustomerService002 ... We are not expected to change the target object, while we need the target name in RequestInterceptor.apply() method to determine whether we should dispatch the service to a cluster.
I think it must be very normal appeals to access the target
.
In my case, all micro service should sign the uri
before request.
The sign rule is common method and need know the app-name wihch define in @FiegnClient(name='xxx-service')
So can feign.SynchronousMethodHandler#invoke
modify like this.
for (RequestInterceptor interceptor : requestInterceptors) {
interceptor.apply(target, template);
}
I think it must be very normal appeals to access the
target
. In my case, all micro service should sign theuri
before request. The sign rule is common method and need know the app-name wihch define in@FiegnClient(name='xxx-service')
So can
feign.SynchronousMethodHandler#invoke
modify like this.for (RequestInterceptor interceptor : requestInterceptors) { interceptor.apply(target, template); }
https://blog.csdn.net/weixin_45357522/article/details/106745468
Based on these comments, what you are looking for is a DynamicTarget
implementation or component available that allows users to provide a Consumer
or Function
that can resolve the endpoint at runtime. I can see the utility of this and I think that's a good idea.
I'll rename this issue to reflect the need. If there is enough interest, we'll convert this into an enhancement and move forward.
Based on these comments, what you are looking for is a
DynamicTarget
implementation or component available that allows users to provide aConsumer
orFunction
that can resolve the endpoint at runtime. I can see the utility of this and I think that's a good idea.I'll rename this issue to reflect the need. If there is enough interest, we'll convert this into an enhancement and move forward.
With 3.x, we can do it now. No need to change for this any more.