7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

非同期でOpenWeatherMap APIを呼び出してみた【Spring WebFlux】

Posted at

はじめに

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キー
    • unitsmetricで摂氏表示

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にマッピングして使用も可能
7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?