Spring Boot 環境で Redoc を活用した API ドキュメントの構築

OpenAPI 仕様に基づくドキュメント生成の概要

Java ecosystem において、API 仕様の標準化と可視化は開発効率に直結する重要な要素です。Spring Boot プロジェクトでは、SpringDoc を利用して OpenAPI 3.0 準拠の仕様書を自動生成し、それを Redoc というレンダリングエンジンで表示させる構成が一般的です。この組み合わせにより、コードの変更を追従した最新のドキュメントを、インタラクティブな UI で提供することが可能になります。

Redoc 導入のメリット

従来の Swagger UI と比較し、Redoc は以下の点で優れています。

  • 可読性の高いレイアウト:3 カラム構成により、ナビゲーション、エンドポイント一覧、詳細情報を同時に確認可能です。
  • 豊富なカスタマイズ性:CSS 変数や設定オブジェクトを通じて、ブランドカラーやフォントを細かく調整できます。
  • パフォーマンス:静的ファイルとして提供されるため、サーバー負荷をかけずに高速な表示を実現します。

環境構築と依存関係の定義

プロジェクトのビルド設定ファイルに、SpringDoc および Redoc 用のライブラリを追加します。ここでは Maven を例示します。

<dependencies>
    <!-- OpenAPI 仕様書の自動生成 -->
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-ui</artifactId>
        <version>1.7.0</version>
    </dependency>

    <!-- Redoc UI ライブラリ (WebJar) -->
    <dependency>
        <groupId>org.webjars.npm</groupId>
        <artifactId>redoc</artifactId>
        <version>2.1.3</version>
    </dependency>
</dependencies>

OpenAPI 設定クラスの作成

アプリケーション起動時に API のメタ情報を定義する設定クラスを用意します。これにより、ドキュメントのタイトルやバージョン、サーバー情報を制御できます。

@Configuration
public class OpenApiSetting {

    @Bean
    public OpenAPI apiDefinition() {
        return new OpenAPI()
            .info(new Info()
                .title("在庫管理システム API")
                .version("2.0.0")
                .description("Redoc を利用した製品カタログ管理インターフェース")
                .license(new License().name("Apache 2.0").url("https://www.apache.org/licenses/LICENSE-2.0")))
            .servers(List.of(
                new Server().url("http://localhost:8080").description("ローカル開発環境"),
                new Server().url("https://api.service.com").description("本番環境")
            ));
    }
}

コントローラーへの注釈追加

実際のエンドポイントに対して、操作の内容やレスポンスコードを注釈で記述します。これにより、生成される仕様書の精度が向上します。

@RestController
@RequestMapping("/api/products")
public class ProductController {

    @Operation(summary = "製品一覧の取得", description = "フィルター条件に基づいて製品リストを返します")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "正常に取得完了"),
        @ApiResponse(responseCode = "403", description = "アクセス権限がありません")
    })
    @GetMapping
    public ResponseEntity<List<ProductDetail>> searchProducts(
            @Parameter(description = "検索キーワード") @RequestParam(required = false) String keyword,
            @Parameter(description = "表示件数") @RequestParam(defaultValue = "50") int limit) {
        
        // 実装ロジック
        return ResponseEntity.ok(Collections.emptyList());
    }
}

Redoc UI の統合実装

生成された OpenAPI JSON を読み込む HTML ファイルを静的リソースディレクトリに配置します。WebJar を利用する場合、パスは自動的に解決されます。

HTML ファイルの構成 (src/main/resources/static/api-reference.html)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>在庫管理 API リファレンス</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body { margin: 0; padding: 0; font-family: sans-serif; }
    </style>
</head>
<body>
    <redoc spec-url="/v3/api-docs" 
           hide-download-button="true"
           native-scrollbars="true"
           theme='{
             "colors": {
               "primary": { "main": "#009688" },
               "sidebar": { "backgroundColor": "#fafafa" }
             },
             "typography": {
               "fontSize": "14px",
               "lineHeight": "1.5em"
             }
           }'>
    </redoc>
    <script src="/webjars/redoc/2.1.3/bundles/redoc.standalone.js"></script>
</body>
</html>

高度な設定とカスタマイズ

API エンドポイントが多い場合、タググループを使用してナビゲーションを整理できます。また、テーマ設定を外部化することで、維持管理を容易にします。

タググループの定義

@OpenAPIDefinition(
    info = @Info(title = "在庫管理システム API", version = "2.0.0"),
    extensions = {
        @Extension(properties = {
            @ExtensionProperty(name = "x-tagGroups", value = "[{'name': '製品管理', 'tags': ['products']}, {'name': '認証', 'tags': ['auth']}]")
        })
    }
)
public class ApiGlobalConfig {}

セキュリティ設定の適用

ドキュメントページ自体へのアクセス制限をかけることで、内部 API 仕様の漏洩を防ぎます。

@Configuration
@EnableWebSecurity
public class AccessControlConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api-reference.html", "/v3/api-docs/**").hasRole("ADMIN")
                .anyRequest().permitAll()
            )
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }
}

運用上の注意点とトラブルシューティング

本番環境へデプロイする際、文字コードやキャッシュ設定に注意が必要です。

文字化け対策

application.yml にてエンコーディングを明示的に UTF-8 へ設定します。

spring:
  http:
    encoding:
      charset: UTF-8
      enabled: true
      force: true

キャッシュ無効化

開発中に仕様書が更新されない場合、SpringDoc のキャッシュ機能をオフにします。

springdoc:
  cache:
    disabled: true
  swagger-ui:
    enabled: false

本番環境向けの最適化

パフォーマンスと環境依存性の分離を図るための設定例です。

プロファイルによるパス分け

環境ごとに API ドキュムの公開パスを変更し、誤アクセスを防ぎます。

---
spring:
  config:
    activate:
      on-profile: production
springdoc:
  api-docs:
    path: /internal/api-docs
  swagger-ui:
    enabled: false

静的リソースの CDN 配置

Redoc の JavaScript ファイルを CDN ホストから読み込むことで、アプリケーションサーバーの負荷を軽減できます。

<script src="https://cdn.example.com/libs/redoc.standalone.js"></script>

タグ: spring-boot redoc OpenAPI springdoc api-documentation

6月4日 19:11 投稿