-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable dynamically overriding the base URL in HTTP interface #30935
Comments
Hi @mprevisic this, in fact, works in Feign, however it would be a breaking change for us and it might not be a feature that is very commonly used. Seeing that you can already override the entire URI, most scenarios should be handled. For your specific-use case, if there are not too many different base urls you use, you might want to create various clients using the same interface, but with |
Hi @OlgaMaciaszek thanks for your reply. If you don't like the idea of a breaking change, would it be possible, that a path variable like
At the moment this would call something like |
That's not a good enough reason to break compatibility. It would be a regression to someone else whose use case is different from yours. This is not to say that we don't want to make your use case easy. But given where we are today, we'll need to imagine a way in the programming model to make the intent clear. I'm afraid the suggestion for Note also that in our clients (HTTP and WebSocket), you can usually provide a URI template that we expand that into a I'm now wondering about supporting this through a |
Better yet, we can support |
Thanks for your reply @rstoyanchev
Such a break is not nice. However, i think, that most people will migrate from feign to http-interfaces and so they are used to feign behavior. But your suggestion with the
or do we have to do something like:
|
You would be able to do: @GetExchange(value = "/animals/{type}", accept = APPLICATION_JSON_VALUE)
List<Animal> getAnimals(UriBuilderFactory factory, @PathVariable(value = "type") String type)
var uriBuilderfactory = new DefaultUriBuilderFactory("http://example.com");
getAnimals(uriBuilderfactory, "cat"); Internally we would call: var uriTemplate = annotation.url();
var uri = uriBuilderFactory.expand(uriTemplate); which would expand the URI template from the annotation with the base URL in the |
Superseded by #31413. |
Althougth use UriBuilderFactory as a parameter can solve the issue to determine the base url at runtime, but it will need some extra unnessesary code in business logic, in feign, this work can be done on a request interceptor, by setting the target. Dose this product can support this feature? Besides, as I see from document, every declared interface need to be created at a configuration class one by one, but in OpenFeign there's no need to do so. Dose this product can do the same thing as OpenFeign |
@yuexueyang, we provide this method of doing it here. It is rather straightforward. You could also opt for getting your base url for the underlying client from properties. Regarding auto-configuration, I'm working on it now. Track progress under spring-projects/spring-boot#31337. |
@rstoyanchev or @OlgaMaciaszek could you please provide a more detailed example? In the sample code you have writing calling a method inside the interface which has the GetExchange which is not possible theoretically. |
@rezamirali-leanix here is a complete example: import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.util.UriBuilderFactory;
public interface ApiServiceClient {
@GetExchange("/{method}")
String makeApiRequest(UriBuilderFactory uriBuilderFactory, @PathVariable String method);
} import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.support.RestClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.UriBuilderFactory;
@SpringBootApplication
public class IntclientApplication {
public static void main(String[] args) {
SpringApplication.run(IntclientApplication.class, args);
}
@Bean
public ApplicationRunner runCommand(RestClient.Builder builder) {
return new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
RestClient restClient = builder.build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
ApiServiceClient service = factory.createClient(ApiServiceClient.class);
var uriBuilderfactory = new DefaultUriBuilderFactory("http://httpbin.org/");
String result = service.makeApiRequest(uriBuilderfactory, "get");
System.out.println(result);
}
};
}
} |
I have a few use cases in my project, that require me to call the same endpoint on several different base URLs and I need to be able to pass the base URL as a parameter into the method of the client.
Using Feign, this is possible to achieve by just adding a URI as a parameter. In a spring http interface, there is also the possibility to add a URI as a parameter, but the functionality is not the same because here it overwrites the whole path that is set in the HttpExchange annotation. What I want is to provide only the base URL as a parameter but that the path in the annotation gets added to the base URL.
For example,
If i do
and provide https://some.cats.url.com as value for the baseUrl parameter
it will send a request to the URL https://some.url.com but actually what I want to do is to call https://some.url.com/animals/cats.
Thanks!
The text was updated successfully, but these errors were encountered: