Feign: Configuring a fallback in feign clients

Created on 2 Dec 2015  ·  13Comments  ·  Source: OpenFeign/feign

It would be great if we could configure a Hystrix fallback in Feign clients. Any plans to implement this funcionality?

Most helpful comment

In fact the FooFallback must implement FeignFooClient interface to make it work. I'm leaving this comment here in case someone follows this as a guide :)

All 13 comments

can you explain how this request is different than feign-hystrix? (probably
with code is best). Also there have been many requests around hystrix, so
if you do an issue search and find something similar, this will help too!

Hi! I searched the repository for something related and didn't find anything.

This is related to an issue I opened in Spring Cloud Netflix repo: I am using their Feign integration through the use of @FeingClient annotation:

@FeignClient("stories-microservice")
public interface StoryClient {

    @RequestMapping(method = RequestMethod.GET, value = "/stories", params="random")
    String getStory(@RequestParam("random") boolean random);

I have a rest controller that calls this client:

@RestController
@RequestMapping("/api")
@EnableEurekaClient
@EnableFeignClients
@EnableCircuitBreaker
@RefreshScope
@SpringBootApplication
public class StoryTellerApiApplication {

    @Autowired
    private StoryClient sgc;

    @RequestMapping(value="/stories", params="random=true")
    public String getRandomStory(HttpServletResponse response) {
        String randomStory = sgc.getStory(true);

The point is that there is no way of configuring a Hystrix callback for Feign clients. Under the hood feign-hystrix is used:

org.springframework.cloud.netflix.feign.FeignClientFactoryBean;

    Feign.Builder builder = HystrixFeign.builder()
    // required values
    .logger(logger)
    .encoder(get(factory, Encoder.class))
    .decoder(get(factory, Decoder.class))
    .contract(get(factory, Contract.class));

I have been looking for a way of defining hystrix callback methods in the native HystrixFeignBuilder but it seems there isn't any way to do it.

@adriancole this if for defining a Hystrix fallback when there are errors. It was intentionally left out because I didn't know how to define a fallback and it wasn't needed to get simple hystrix support working.

I was wondering about this, too. Maybe something with an @Fallback annotation that can be added to methods that points to static methods on an extension of the client interface.

public interface FooClient {
      void doSomething(String withArg);
}

@FeignClient("foo-client")       
public interface FeignFooClient extends FooClient {

    @Override
    @RequestMapping(method = RequestMethod.GET, value = "/something/{withArg}")
    @Fallback("trySomethingElse")
    SomethingResponse doSomething(String withArg);

    static SomethingResponse trySomethingElse(String withArg) {
        ...
    }
}       

This assumes you don't own the FooClient interface. If you do own that code, you could put the annotations directly on that interface.

@dnathanson a static fallback won't be enough for me. I need it to be an instance that is looked up by some mechanism, so it can be properly configured.

How about a fallback implementation of the interface?

public interface FooClient {
      void doSomething(String withArg);
}

public class FooFallback implements FooClient {
      public void doSomething(String withArg){
            System.out.println(withArg);
       }
}

@FeignClient(name="foo-client", fallback=FooFallback.class)       
public interface FeignFooClient extends FooClient {

    @Override
    @RequestMapping(method = RequestMethod.GET, value = "/something/{withArg}")
    void doSomething(String withArg);

}  

I like that. There would need to be some kind of factory interface to create the impl. Default to new it using reflection, but allow spring or guice to look it up.

FeignClient is specific to spring Cloud Netflix BTW.

How about a fallback implementation of the interface?

public interface FooClient {
void doSomething(String withArg);
}
public class FooFallback implements FooClient {
public void doSomething(String withArg){
System.out.println(withArg);
}
}

I like this.. I think that we could address this in the
HystrixFeignBuilder, ex add an arg for instance of T which is the fallback.
This makes the feature wiring agnostic.

here t'is https://github.com/Netflix/feign/pull/308 cc @jdamick who's been quiet lately :P

I like this.when this implementation can we use?

public interface FooClient {
      void doSomething(String withArg);
}

public class FooFallback implements FooClient {
      public void doSomething(String withArg){
            System.out.println(withArg);
       }
}

@FeignClient(name="foo-client", fallback=FooFallback.class)       
public interface FeignFooClient extends FooClient {

    @Override
    @RequestMapping(method = RequestMethod.GET, value = "/something/{withArg}")
    void doSomething(String withArg);

}  

Sounds reasonable, just needs to get into the right issues list
https://github.com/spring-cloud/spring-cloud-netflix/issues

In fact the FooFallback must implement FeignFooClient interface to make it work. I'm leaving this comment here in case someone follows this as a guide :)

Was this page helpful?
0 / 5 - 0 ratings