エンジニアを目指す初学者に向けて、わかりやすく解説したブログです。
サイトをリニューアルしました

SpringBootでWebFluxを用いたAPIの環境構築をする(Gradle)

概要

SpringBootのプロジェクトを初期化し、「Hello World」を表示するところまでを行う。

APIを構築する場合には「Spring MVC」と「Spring WebFlux」を選ぶ必要があるが
今回は非同期的にリクエストを処理できるWebFluxを採用する。

参考:Icon in a page linkSpring クイックスタート - 公式サンプルコード

その前に、Javaの環境構築が必要な人はこちら

📄Arrow icon of a page linkMacにJavaをインストールする方法(SDKMAN!)

プロジェクト初期化

VSCodeの拡張機能を使って初期化するやり方や、IntelliJを使って初期化するやり方があるが、
今回はエディタに依存しない説明をするため、以下のSpring initializrを用いて解説する。

📄start.spring.io

上記のサイトで、必要な情報を入力する。

Image in a image block
  • Group:企業で作る場合、企業のドメインなどをよく入れる
  • Aftifact,Name:これはシステム名を入れればよい
  • Dependencies:初期状態から入れておきたいライブラリなどはこの時点で選択できる
    • Spring Boot Dev Tools:ホットリードできるのでマストで入れておく
    • Lombok:便利なアノテーションが使えるので入れる
    • Spring Configuration Processor:設定ファイルの読み込みを便利にする
  • Spring Reactive Web:WebFluxを使うため

zipファイルがダウンロードできるので、これを解凍すれば良い。

Image in a image block

アプリケーション構成

初回は以下のようなディレクトリ構成になるはず。

Image in a image block

Controllerを作成する

apiディレクトリの下に、 controller/SampleController.javaを作成する。

Image in a image block

中身は以下の通り。

package com.example.api.controller;

import org.springframework.web.bind.annotation.RestController;

import reactor.core.publisher.Mono;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;


@RestController
public class SampleController {
  
  @GetMapping("/")
  public Mono<String> getMethodName() {
    return Mono.just("Hello World.");
  }
}
  • APIとして使うControllerには @RestControllerアノテーションを使う
  • @GetMapping("/")で、「/にGETリクエストが来たとき」となる
  • WebFluxなので、全て Monoでラップする

アプリケーションを起動する

通常起動するためには gradleコマンドの用意が必要だが、
Spring Initializrを使って初期化する場合、ルートディレクトリに gradlewコマンドが配置されている。

起動コマンドは以下の通り。

$ ./gradlew bootRun

> Task :bootRun

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.4.2)

2025-02-09T23:02:00.888+09:00  INFO 56759 --- [api] [  restartedMain] com.example.api.ApiApplication           : Starting ApiApplication using Java 23.0.2 with PID 56759 (/Users/username/workspace/apps/api/build/classes/java/main started by username in /Users/username/workspace/apps/api)
2025-02-09T23:02:00.892+09:00  INFO 56759 --- [api] [  restartedMain] com.example.api.ApiApplication           : No active profile set, falling back to 1 default profile: "default"
2025-02-09T23:02:01.117+09:00  INFO 56759 --- [api] [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2025-02-09T23:02:01.118+09:00  INFO 56759 --- [api] [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2025-02-09T23:02:02.402+09:00  INFO 56759 --- [api] [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2025-02-09T23:02:02.504+09:00  INFO 56759 --- [api] [  restartedMain] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port 8080 (http)
2025-02-09T23:02:02.513+09:00  INFO 56759 --- [api] [  restartedMain] com.example.api.ApiApplication           : Started ApiApplication in 2.097 seconds (process running for 2.637)
<==========---> 80% EXECUTING [16s]
> :bootRun

アプリケーションの動作確認をする

localhost:8080にアクセスすると、以下のようにHello Worldが表示されることが確認できる。

Image in a image block

JSONオブジェクトを返す

JSONを返すためには、レスポンス用のクラスを作ってそれを返却するだけで良い。

DemoResponse.javaを新規作成

// DemoResponse.java
package com.example.api.controller;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class DemoResponse {
  private final String name;
  private final String message;
}
  • @Getterで、 getName()メソッドや getMessage()メソッドを自動生成する
  • @RequiredArgsConstructorで、finalがついているフィールドを対象にしたコンストラクタを自動生成する

これらはLombokの機能でかなり便利なので覚えておくと良い。

package com.example.api.controller;

import org.springframework.web.bind.annotation.RestController;

import reactor.core.publisher.Mono;

import org.springframework.web.bind.annotation.GetMapping;


@RestController
public class SampleController {
  
  // 返却する型をDemoResponseにする
  @GetMapping("/")
  public Mono<DemoResponse> getMethodName() {
    final DemoResponse demo = new DemoResponse("Hello", "World");
    return Mono.just(demo);
  }
}

このようにすることで、以下のようにJSONが返却されるようになる。

Image in a image block

ホットリロードができるようにする

application.ymlの設定

IDE系であれば、 src/main/resources/application.ymlに以下の設定を行うだけで良いはず。

spring:
  application:
    name: api
  devtools:
    livereload:
      enabled: true
    restart:
      enabled: true

※初期状態は application.propertiesというファイルだが、ymlのほうが読みやすいので筆者はymlにしている。
(どちらのフォーマットでもSpringは自動で読み込んでくれる)

参考:Icon in a page link開発者ツール :: Spring Boot - リファレンスドキュメント

実行コマンド

./gradlew bootRunを実行しているものとは別のターミナルで、以下のコマンドを打っておくことでファイルの変更を監視できるようになる。

./gradlew -t classes

-tオプションは、継続的なビルドを有効化し、引数に入れるタスクに変更があったときに再実行するオプション。

タスクは以下の通り。

Icon in a page linkThe Java Plugin