FeignClient: если ответ API имеет два разных формата, как элегантно справиться с таким случаем? - PullRequest
0 голосов
/ 14 февраля 2020

В моем проекте есть Feignclient, как показано ниже:

@FeignClient(name = "myFeignClient", url = "${remote-url}", configuration = {MyApiClient.Config.class})
public interface ApiClient {

    @PostMapping(value = "/product", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    ProductDTO getProduct(@RequestBody ProductReqParam req);

    ... // other @GetMapping or @PostMapping method is ignored here

    class Config {
        @Bean
        ErrorDecoder errorDecoder() {
            return new FeignErrorDecoder();
        }

        static class FeignErrorDecoder implements ErrorDecoder {
            @Override
            public Exception decode(String methodKey, Response response) {
                if (response.body() != null) {
                    return new MyFeignException(response.status(), response.body().toString());
                } else {
                    return new MyFeignException(response.status());
                }
            }
        }
    }

}

в соответствии с API-документом нашего стороннего провайдера, ProductDTO выглядит как

public class ProductDTO {

    @JsonProperty("Result")
    private ProductDTO.Result result;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Result {
        @JsonProperty("STATUS")
        private String status;
        @JsonProperty("TOTALRECORD")
        private Integer recordCount;
        @JsonProperty("DATA")
        private List<Product> productList;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Product {
        @JsonProperty("ID")
        private Integer id;
        @JsonProperty("NAME")
        private String name;
        @JsonProperty("PRICE")
        private String price;
    }  
}

, но после проекта запускается в производственной среде, мы обнаруживаем, что если существует только одна запись о продукте, возвращаемое значение JSON, соответствующее ключу «DATA», равно JSON вместо JSON Array ,, поэтому ProductDTO будет иметь поле, подобное этому:

 @JsonProperty("DATA")
 private Product product;

Да, сторонний разработчик API проделал очень плохую работу, построив свой ответ нам, они должны поместить один объект в список и затем вернуться к нам, но они этого не делают поэтому нам приходится иметь дело с двумя разными ответами самим.

Я не знаю, как справиться с таким случаем. Мой первоначальный план состоит в том, чтобы внедрить настроенный bean-компонент feignDecoder, в методе декодирования специально для этого используется API "/ product". Но это будет мешать другим методам, также у меня уже есть компонент ErrorDecoder, который может вызвать потенциальные проблемы?

...