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 を付けると pagesize パラメータが自動でドキュメント化されます。ページネーションの実装については 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 で確実に無効化する

フロントエンドチームとのコミュニケーションが格段に楽になりますよ。