背景
SpringBootでAPIを使用しようと思ったらRestTemplateを使うと思いますが、RestTemplateはメンテナンスモードに入ってしまい、他のClientに変えざるおえない人も多数だと思います。
私もあるプロジェクトで変える必要発生し、FeignClientに変更しました。
ここで特定のエラー時はFeignExceptionを返すのではなく、自作例外を返却したい時がありました。
環境
Java:17
Gradle:8.5
SpringBoot:3.1.6
spring-cloud-starter-openfeign:4.0.4
最初にやってみたこと
ErrorDecoderを自作しそれをBean化させて特定のFeignClientに装着させれば可能です。
※基本的なFeignClientの使い方は割愛します
@RequiredArgsConstructor
public class CustomDecoder implements ErrorDecoder {
private final ObjectMapper mapper;
@Override
public Exception decode(String methodKey, Response response) {
return new CustomException(); // ここで自作例外を返す
}
}
@Configuration
@RequiredArgsConstructor
public class FeignConfig {
private final ObjectMapper mapper;
@Bean
ErrorDecoder errorDecoder() {
return new CustomDecoder();
}
}
@FeignClient(configuration = FeignConfig.class) // configurationに設定クラスを代入するとClientに設定が適用される。
public interface HogeClient {
@GetMapping(value = "/fugaEndopoint")
void getXXX();
}
これで設定完了です!
いざ実践!あれ?記載していない他のFeignClientにも適用されている!
一体何故。。。。
原因
なんとデフォルトでErrorDecoderを設定していないと、全FeignClientに装着されてしまうのです。
<参照>
- https://stackoverflow.com/questions/56352215/how-implement-error-decoder-for-multiple-feign-clients
- https://github.com/spring-cloud/spring-cloud-openfeign/issues/72
解決方法
デフォルトのErrorDecoder全FeignClientに適用後、特定のFeignClientには専用のErrorDecoderをBean化させ上書きさせるです。
→色々調査したのですが、ベストプラクティスが不明だったので私が行った対策です。
application.ymlに記載でもよかったのですが、デフォルトのFeignClientの設定をBean化して設定していたので、ymlファイルに記載はあんまり気乗りしませんでした。
@Configuration
@RequiredArgsConstructor
public class FeignConfig {
private final ObjectMapper mapper;
/**
* @Bean {
* ErrorDecoder errorDecoder {
* return new CustomDecoder();
* }
* }
*/
@Bean
ErrorDecoder errorDecoder() {
return new ErrorDecoder.Default(); // デフォルトのErrorDecoderをBean化
}
}
@Configuration
@RequiredArgsConstructor
public class CustomFeignConfig {
private final ObjectMapper mapper;
@Bean
ErrorDecoder customErrorDecoder() { //errorDecoderの名前にすると同一Bean名になってしまうので注意
return new CustomDecoder(mapper);
}
}
いざ実践!
問題なく対応した例外が投げられている!
こうして特定のFeignClientには専用のErrorDecoderを適用することができました。
最後に
はまった人がいれば、解決の一例としてやってみてください。
他にもこんな方法や、指摘点だどございましたらコメントください。
にしてもFeign関係は資料が少なくて困る。。。。あとRestClientの方が使い易いから早く変えたい。。。