Spring Boot で実装する
🐱 この章の目次
演習プロジェクトの構成
Part 1 で学んだ Spring Boot を使い、前章の注文 API を実装します。 Spring Boot は HTTP サーバー、JSON 変換、依存性注入、外部設定を一つのアプリケーションとして構成します。
最初に Spring Initializr から JDK 21、Gradle Kotlin DSL、Spring Web を選んでプロジェクトを生成します。 コマンドで取得する場合は次のとおりです。
curl -fLG https://start.spring.io/starter.zip \
--data-urlencode type=gradle-project-kotlin \
--data-urlencode language=java \
--data-urlencode bootVersion=4.1.0 \
--data-urlencode javaVersion=21 \
--data-urlencode groupId=com.example \
--data-urlencode artifactId=orders \
--data-urlencode name=orders \
--data-urlencode baseDir=orders \
--data-urlencode dependencies=web \
-o orders.zip
unzip orders.zip
cd orders
生成された gradlew、gradlew.bat、gradle/wrapper/ はプロジェクトと一緒にバージョン管理します。
build.gradle.kts には Spring MVC と springdoc-openapi を追加します。
plugins {
java
id("org.springframework.boot") version "4.1.0"
id("io.spring.dependency-management") version "1.1.7"
}
group = "com.example"
version = "1.0.0"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-webmvc")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:3.1.0")
testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
tasks.test {
useJUnitPlatform()
}
Spring Boot プラグインが依存バージョンを管理するため、Spring Framework や Jackson のバージョンを個別に並べません。 springdoc-openapi は別プロジェクトなので、互換するバージョンを明示します。
アプリケーションの起点
OrderApplication.java を作ります。
package com.example.orders;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
@SpringBootApplication は、構成クラス、コンポーネント探索、自動構成の起点です。
JVM や Java 言語の機能ではなく、Spring Boot が解釈するアノテーションです。
REST エンドポイント
レスポンスの型を Order.java に置きます。
package com.example.orders;
public record Order(String orderId, String status) {}
注文を探す処理は OrderService.java に置きます。
この段階では、動作確認用の一件だけを返します。
package com.example.orders;
import java.util.Optional;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
public Optional<Order> find(String orderId) {
if (!orderId.equals("abc-123")) {
return Optional.empty();
}
return Optional.of(new Order(orderId, "shipped"));
}
}
OrderController.java に、OpenAPI 契約と同じ GET のパス、パラメータ、ステータスを実装します。
package com.example.orders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderService orderService;
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@GetMapping("/{orderId}")
public ResponseEntity<Order> getOrder(
@PathVariable String orderId) {
return orderService.find(orderId)
.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.notFound().build());
}
}
@RestController は戻り値を HTTP レスポンスへ変換し、@GetMapping は HTTP メソッドとパスを対応づけます。
Java の record はレスポンスのフィールドを型として明示し、Jackson が JSON へ変換します。
起動して契約を確認する
./gradlew bootRun
curl http://localhost:8080/orders/abc-123
http://localhost:8080/swagger-ui.html で Swagger UI、http://localhost:8080/v3/api-docs で実装から生成された OpenAPI 文書を確認できます。
手書きの openapi.yaml と実装由来の文書を比較すると、構造上の差異を確認できます。
この章では GET と 404 を実装し、次章で POST、201、400 を実装して契約へ追いつきます。
FastAPI との対応
FastAPI では関数と型ヒントからルートやスキーマを組み立てます。 Spring Boot ではコントローラー、Bean Validation、DI コンテナ、自動構成を組み合わせます。 この教室では後者を主演習にし、Part 4 で同じ JVM プロセスへ OpenTelemetry Java Agent を取り付けます。