I have a Spring boot application which uses Feign to call an external web service via Eureka. I'd like to be able to run the application using a mocked out implementation of the Feign interface, so I can run the application locally without necessarily having Eureka or the external web service running. I had imagined defining a run configuration that allowed me to do this, but am struggling to get this working. The issue is that the Spring "magic" is defining a bean for the Feign interface no matter what I try.
Feign interface
@FeignClient(name = "http://foo-service")
public interface FooResource {
@RequestMapping(value = "/doSomething", method = GET)
String getResponse();
}
Service
public class MyService {
private FooResource fooResource;
...
public void getFoo() {
String response = this.fooResource.getResponse();
...
}
}
I tried adding a configuration class that conditionally registered a bean if the Spring profile was "local", but that was never called when I ran the application with that Spring profile:
@Configuration
public class AppConfig {
@Bean
@ConditionalOnProperty(prefix = "spring.profile", name = "active", havingValue="local")
public FooResource fooResource() {
return new FooResource() {
@Override
public String getResponse() {
return "testing";
}
};
}
}
At the point my service runs, the FooResource
member variable in MyService
is of type
HardCodedTarget(type=FoorResource, url=http://foo-service)
according to IntelliJ. This is the type that is automatically generated by the Spring Cloud Netflix framework, and so tries to actually communicate with the remote service.
Is there a way I can conditionally override the implementation of the Feign interface depending on a configuration setting?
Let's implement the Feign in our project and invoke other microservices using Feign. Step 1: Select currency-conversion-service project. Step 2: Open the pom. xml and add the Feign dependency.
Yes you can use Feign without Ribbon, All you need to do is specify the base url in your Feign Java interface class.
Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders.
Feign is a declarative web service client that makes writing web service clients easier. To use Feign, create an interface and annotate it with @FeignClient. It has pluggable annotation support including Feign and JAX-RS annotations. Feign is a declarative web service client. It makes writing web service clients easier.
The parameters will be modeled using the @Param annotation: NOTE: Feign clients can be used to consume text-based HTTP APIs only, which means that they cannot handle binary data, e.g. file uploads or downloads. That's all!
Good things is you can change these global configurations from property file such as connection timeout, read timeout and logger level You can also configure each feign client individually from property file using feign client name or value.
Feign Integration with Spring Cloud With maven, we include spring-cloud-starter-openfeign artifact in our pom.xml file annotate the main class with the annotation @EnableFeignClients. Once, this is done we create an interface that has the abstract implementation of our HTTP client and annotate it with @FeignClient.
the solution is like below:
public interface FeignBase {
@RequestMapping(value = "/get", method = RequestMethod.POST, headers = "Accept=application/json")
Result get(@RequestBody Token common);
}
then define your env based interface:
@Profile("prod")
@FeignClient(name = "service.name")
public interface Feign1 extends FeignBase
{}
@Profile("!prod")
@FeignClient(name = "service.name", url = "your url")
public interface Feign2 extends FeignBase
{}
finally, in your service impl:
@Resource
private FeignBase feignBase;
Having posted the same question on the Spring Cloud Netflix github repository, a useful answer was to use the Spring @Profile
annotation.
I created an alternative entry point class that was not annotated with @EnabledFeignClients
, and created a new configuration class that defined implementations for my Feign interfaces. This now allows me to run my application locally without the need to have Eureka running, or any dependent services.
I'm using a simpler solution to avoid having multiples interfaces for a variable parameter like url.
@FeignClient(name = "service.name", url = "${app.feign.clients.url}")
public interface YourClient{}
application-{profile}.properties
app.feign.clients.url=http://localhost:9999
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With