はじめに
Spring Bootでは、これまでRestTemplate
が主流でしたが、現在は非同期・ノンブロッキングなWebClient
への移行が推奨されています。
本記事では、気候関連情報取得するOpenWeatherMap APIを題材に、WebClient
で外部APIを非同期に呼び出す方法を紹介します。
なぜWebClientなのか?(RestTemplateとの違い)
項目 | RestTemplate | WebClient |
---|---|---|
I/O | ブロッキング | ノンブロッキング |
スレッド使用量 | 多い | 少ない |
リアクティブ対応 | × | ○ |
今後のサポート | 非推奨 | メイン推奨 |
WebClientはSpring WebFluxのリアクティブな世界と相性が良く、パフォーマンスやスケーラビリティの面でも有利です。
プロジェクトの準備
本記事ではbuild.gradle
を使用:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
}
OpenWeatherMap APIの概要
- エンドポイント:
https://api.openweathermap.org/data/2.5/weather
- パラメータ:
-
q
:都市名(例:Tokyo) -
appid
:APIキー -
units
:metric
で摂氏表示
-
DTO
public record WeatherResponse(String name, Main main, Weather[] weather) {
public record Main(double temp) {}
public record Weather(String main, String description) {}
}
Controller
@RestController
@RequestMapping("/api/weather")
public class WeatherController {
private final WeatherService weatherService;
public WeatherController(WeatherService weatherService) {
this.weatherService = weatherService;
}
@GetMapping
public Mono<WeatherResponse> fetchWeather(@RequestParam String city) {
return weatherService.getWeather(city);
}
}
リクエスト例:
GET /api/weather?city=Tokyo
Service
@Service
public class WeatherService {
private final WebClient webClient;
public WeatherService(WebClient.Builder builder) {
this.webClient = builder.baseUrl("https://api.openweathermap.org/data/2.5").build();
}
public Mono<WeatherResponse> getWeather(String city) {
return webClient.get()
.uri(uriBuilder -> uriBuilder
.path("/weather")
.queryParam("q", city)
.queryParam("appid", "YOUR_API_KEY")
.queryParam("units", "metric")
.build())
.retrieve()
.bodyToMono(WeatherResponse.class);
}
}
実行結果例
{
"name": "Tokyo",
"main": {
"temp": 23.4
},
"weather": [
{
"main": "Clear",
"description": "clear sky"
}
]
}
まとめ
- WebClientは非同期・ノンブロッキングで高性能
-
Mono<String>
だけでなくDTOにマッピングして使用も可能