8

I have a Feign client that requests a token from a microservice. Since I am making multiple calls, I would like to cache the responses received from the Feign client and use Spring Guava caching, but it doesn't seem to work. All I have is the configuration class and the annotation on the Feign client.

I read somewhere on stack overflow that Feign might not support @Cacheable annotation. Is this true?

Didier L
  • 18,905
  • 10
  • 61
  • 103
Bianca
  • 779
  • 3
  • 9
  • 19

3 Answers3

10

Finally, I managed to solve my issue. What I did in the end is :

-> Create new @Service annotated class

-> Inject interface with @FeignClient annotation

-> Put all @Cache related annotations ( using @Caching annotation) on the method that calls methods from the interface.

It works! :)

Bianca
  • 779
  • 3
  • 9
  • 19
6

Annotating Feign clients with @Cacheable now works out of the box with Spring Cloud OpenFeign, as per the documentation, since version 3.1.0 (as part of Spring Cloud 2021.0.0).

You only need to make sure that:

Didier L
  • 18,905
  • 10
  • 61
  • 103
4

What Bianca supposed to do is to add a @Service annotated class to her project where she can use @cacheable annotation.

The traditional way to use FeignClient is to have only an interface annotated with @FeignClient, and then call these methods form other projects/classes. She has added a @Service annotated class, where she call her feignclients methods caching whatever she want.

Traditional:

FeignClient class:

@FeignClient(name="my_feign-client", url = "http://myurl.com/")
public interface MyFeignClient {
    @GetMapping("/test")
    public ResponseEntity<String> test() throws FeignException;

Class where to call feign client method:

public class TestClass {
    @Autowired
    private MyFeignClient myFeignClient ;
    
    public String callTest() {
    ...
        return myFeignClient.test();
    }

Bianca's method:

Feign client class remains the same.

Service class with cache:

@Service
@CacheConfig(cacheNames={"test"})
public class TestService {
    @Autowired
    private MyFeignClient myFeignClient ;
    
    @Cacheable
    public String callCachedTest() {
    ...
    return myFeignClient.test();
}

And last, the class to call the cached method, that call feignClient:

public class TestClass {
    @Autowired
    private TestService testService ;
    
    public String callTest() {
    ...
        return testService.callCachedTest();
    }