Spring BootでOpenAPI(Swagger UI)を使ってREST APIドキュメントを自動生成する方法
REST APIを実装したあと、「ドキュメントを書いてください」と言われて途方に暮れた経験はありませんか。手書きのExcel管理は更新が漏れがちですし、Notionに書いても実装との乖離がじわじわ広がりますよね。
springdoc-openapi を使えば、コードからAPIドキュメントを自動生成できます。アノテーションを少し追加するだけで、Swagger UIというきれいなWeb画面でAPIを確認・実行できるようになります。この記事では導入から実践的な使い方まで順番に説明します。
springfoxからspringdoc-openapiへ
Spring Bootでのドキュメント自動生成といえば、かつては springfox が主流でした。ただ、Spring Boot 2.6以降で互換性の問題が多発し、現在はメンテナンスも停滞しています。既存プロジェクトでspringfoxを使っていて謎のエラーに悩まされている方も多いはずです。
springdoc-openapi はOpenAPI 3.0準拠で、Spring Boot 3系にも正式対応しています。新規プロジェクトならspringdoc一択といっていいでしょう。
依存関係の追加
Maven
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
Gradle
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
Spring Boot 2系を使っている場合は springdoc-openapi-ui(バージョン1.x系)を使います。アーティファクトIDが異なるので注意してください。本記事はSpring Boot 3系を前提にしています。
まずSwagger UIを確認する
依存を追加してアプリを起動するだけで、Swagger UIがすぐに使えます。
- Swagger UI:
http://localhost:8080/swagger-ui/index.html - OpenAPI JSON:
http://localhost:8080/v3/api-docs
既存のControllerが自動スキャンされ、エンドポイント一覧が表示されます。何も設定しないのにここまで動くのはちょっと感動しますよね。
API情報とJWT認証の設定
Swagger UIのタイトルや説明をカスタマイズするには、設定クラスに OpenAPI Beanを定義します。JWT認証付きプロジェクトなら、SecuritySchemeも同時に設定しておくのが定番です。
@Configuration
@SecurityScheme(
name = "bearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
)
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("My API")
.version("1.0.0")
.description("サンプルAPIのドキュメント"));
}
}
@SecurityScheme を付けておくと、Swagger UIの右上に Authorize ボタンが表示されます。そこにJWTトークンを入力すると、以降のリクエストに Authorization: Bearer {token} が自動で付きます。JWTの取得方法や認証フローの実装については Spring BootでJWT認証を実装する方法 も参考にしてください。
@Operationでエンドポイントを説明する
コントローラーのメソッドに @Operation を付けると、エンドポイントの説明がSwagger UIに表示されます。@Tag でエンドポイントをグループ化し、@Parameter でパスパラメータやクエリパラメータの説明も追加できます。
@RestController
@RequestMapping("/users")
@Tag(name = "Users", description = "ユーザー管理API")
public class UserController {
@Operation(summary = "ユーザー取得", description = "指定したIDのユーザー情報を返します")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "取得成功"),
@ApiResponse(responseCode = "404", description = "ユーザーが見つかりません")
})
@GetMapping("/{id}")
public ResponseEntity<UserResponseDto> getUser(
@Parameter(description = "ユーザーID", example = "1")
@PathVariable Long id
) {
// 実装
}
@Operation(summary = "ユーザー作成")
@SecurityRequirement(name = "bearerAuth")
@PostMapping
public ResponseEntity<UserResponseDto> createUser(
@RequestBody UserRequestDto dto
) {
// 実装
}
}
@SecurityRequirement(name = "bearerAuth") を付けたエンドポイントは、Swagger UIで鍵アイコンが表示されます。Authorizeで設定したトークンが自動的に使われるので、JWT保護されたエンドポイントも画面から手軽にテストできます。
400や404などのエラーレスポンスは @ApiResponse で明記しておくとフロントエンドチームが実装しやすくなります。例外処理の統一的な実装については Spring BootのREST APIで例外処理を統一する方法 も合わせてどうぞ。
@SchemaでDTOのフィールドを説明する
DTOクラスに @Schema を付けると、フィールドの説明とサンプル値がSwagger UIに表示されます。
public class UserRequestDto {
@Schema(description = "ユーザー名", example = "山田太郎")
@NotBlank
private String name;
@Schema(description = "メールアドレス", example = "[email protected]")
@Email
private String email;
}
@NotBlank や @Email などのバリデーションアノテーションは、springdoc-openapiが自動的に読み取って required フラグや format として反映します。アノテーションを2度書く必要がないのは便利ですよね。バリデーションの詳しい実装については Spring Bootの@Validアノテーションでバリデーションを実装する方法 を参照してください。
ページネーション対応APIで Pageable をそのまま受け取っている場合は @ParameterObject を付けると page や size パラメータが自動でドキュメント化されます。ページネーションの実装については Spring BootのREST APIにページネーションを実装する方法 も参考にしてください。
YAML/JSONの取得とCI連携
OpenAPI仕様ファイルはcurlで簡単に取得できます。
# JSON形式
curl http://localhost:8080/v3/api-docs
# YAML形式
curl http://localhost:8080/v3/api-docs.yaml -o api-docs.yaml
取得したYAMLを openapi-generator に渡せば、TypeScriptやKotlinのクライアントコードを自動生成できます。このYAMLをリポジトリにコミットしておくと、APIの変更差分をCIで検知することもできます。
本番環境でSwagger UIを無効にする
Swagger UIを公開したまま本番リリースするのは避けましょう。application-prod.properties に2行追加するだけで無効化できます。
springdoc.swagger-ui.enabled=false
springdoc.api-docs.enabled=false
Spring Profilesを使った環境別設定については Spring BootのProfileで環境設定を切り替える方法 も参考にしてください。
まとめ
springdoc-openapiの導入から実践的な使い方まで紹介しました。依存を1つ追加するだけでSwagger UIが動き出すのは本当に手軽で、段階的にアノテーションを追加しながらドキュメントを育てていけます。
@Operation@ApiResponse@Schemaでドキュメントを段階的に充実させる@SecurityScheme+@SecurityRequirementでJWT認証エンドポイントもSwagger UIから実行できる/v3/api-docs.yamlでCI連携やクライアントコード生成の入口になる- 本番環境では
enabled=falseで確実に無効化する
フロントエンドチームとのコミュニケーションが格段に楽になりますよ。