How to decode JSon response with custom Feign client?

11,002

Another way could be annotating the class with @Import(FeignClientsConfiguration.class) which is the default configuration provided by Spring Cloud Netflix.

Then it becomes easy to inject both Encoder and Decoder when creating the Feign client:

    @Import(FeignClientsConfiguration.class)
    @Configuration
    public class MyConfiguration {
    (...)
    Myclient myClient (Decoder feignDecoder, Encoder feignEncoder) {
    return Feign.builder()
        .decoder( feignDecoder )
        .encoder( feignEncoder )
        .target(
          Target.EmptyTarget.create(
            MyClient.class
          )
        );
    }

There are two different defined encoders in the configuration class (pageable or not), so pay attention to clearly identify which you want, either by its name or a qualifier.

Share:
11,002
Ticker
Author by

Ticker

Updated on June 27, 2022

Comments

  • Ticker
    Ticker almost 2 years

    In my application, I have to know, from a list a server addresses, which are up. The solution I found is to call health endpoint from Spring-Boot Actuator, for each of them. The JSon reponse is:

    {
        "status": "UP"
    }
    

    In other parts of the application, I use Feign clients from Spring-Cloud defined with the @FeignClient annotation, which works perfectly:

        @FeignClient(
                name = "tokenProxy",
                url = "${host}:${port}"
        )
    

    Unfortunately this kind of configuration doesn't allow to re-use the same client to call the same endpoint on different addresses. So I have to define my own custom client (If there is another solution, do not hesitate to tell me! ):

        @GetMapping(
          value = "/servers"
        )
        public Server discover() {
          MyClient myClient = Feign.builder()
            .target(
              Target.EmptyTarget.create(
                MyClient.class
              )
            );
    
          return myClient.internalPing(URI.create("http://localhost:8090"));
        }
    
        interface MyClient {
            @RequestLine("GET /actuator/health")
            Server internalPing(URI baseUrl);
        }
    
        class Server {
            private final String status;
    
            @JsonCreator
            public Server(@JsonProperty("status") String status) {
                this.status = status;
            }
    
            public String getStatus() {
                return status;
            }
        }
    

    When I call the endpoint /servers, I get the following error, indicating that my custom Feign client isn't confgured with the appropriate decoder:

    feign.codec.DecodeException: class com.xxx.web.Server is not a type supported by this decoder.
        at feign.codec.StringDecoder.decode(StringDecoder.java:34) ~[feign-core-10.10.1.jar:na]
        at feign.codec.Decoder$Default.decode(Decoder.java:92) ~[feign-core-10.10.1.jar:na]
        at feign.AsyncResponseHandler.decode(AsyncResponseHandler.java:115) ~[feign-core-10.10.1.jar:na]
        at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:87) ~[feign-core-10.10.1.jar:na]
        at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138) ~[feign-core-10.10.1.jar:na]
    

    I guess i should use JacksonDecoder, but I cannot find it in my dependencies from Spring-Cloud Hoxton.SR5:

          <dependencies>
        ...
            <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
        ...
          </dependencies>
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR5</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
      </dependencyManagement>
    

    Could someone help me, either with a better solution for my need or a explanation on how to properly configure custom Feign clients?

    Thanks in advance