spring-bootfeignopenfeign

API response return different structure cause conversion error


I have this json response back from API:

With result:

{
  "Result": {"name":"Jason"},
  "Status": 1
}

Without result:

{
  "Result": "Not found",
  "Status": 1
}

As you can see the format the different.

When using Feign when not found I will certainly hit the conversion error:

@GetMapping(path = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseDto sendRequest(@RequestParam("id") String ID);
}

Any way to resolve this without changing the API? I will certainly hit with an error

Cannot construct instance of `com.clients.dto.ResponseDto` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Not found.')

Solution

  • You can use generics to solve the issue.

    public class ResponseDto<T>{
    
    private T Result;
    private Long Status;
    
    ...getters and setters....
    
    }
    

    maybe create model for another class as well:

    public class SuccessResult{
    
    private String name;
    
    ...getters and setters....
    
    }
    

    Now in Feign:

    @GetMapping(path = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
        public <T> ResponseDto<T> sendRequest(@RequestParam("id") String ID);
    }
    

    OR....

    @GetMapping(path = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseDto<?> sendRequest(@RequestParam("id") String ID);
    }
    

    After you get the response use object mapper to convert the value:

    import com.fasterxml.jackson.databind.ObjectMapper;
    
    .....
    
    @Autowired
    ObjectMapper objectMapper;
    
    //....your method and logic...
    
    ResponseDto responseDto = sendRequest("1");
    
    String res = null;
    String successResponse = null;
    
    
    if(responseDto.getResult() instanceof String)
    {
        res = objectMapper.convert(responseDto.getResult(), String.class);
    
    } else{
    
        successResponse = objectMapper.convert(responseDto.getResult(), SuccessResult.class);
    
    }