Next.jsを使ってOpenAPIドキュメントを簡単にホストする方法

2025-05-05

Next.jsのプロジェクトでOpenAPIのドキュメントをホストするのが思った以上に簡単でした。
なるべくNext.jsの標準機能を利用することで拡張性と開発体験を損なわず、それでいてシンプルな実装を実現できました。

ディレクトリ構成

ディレクトリ構成やファイルの置き場所は自由にカスタマイズできますが、今回はこの想定で書いています。

app
└── api
    ├── spec
    │   └── route.ts - 定義ファイルを返すAPI
    ├── docs
    │   └── page.tsx - ドキュメントページ
    └── openapi.json (or yaml)

定義ファイルを返すAPI

OpenAPIの定義ファイルをホストするためのエンドポイントを用意します。 app/api/spec/route.tsを作ります。

app/api/spec/route.ts
import openapi from "../openapi.json";

export async function GET() {
  return Response.json(openapi);
}

これだけで/api/specにアクセスするとOpenAPIの定義ファイルが返ってきます。

YAML形式の場合はimportできないので、fsモジュールを使って読み込むように書き換えてください。

ドキュメントページ

ドキュメントページには Swagger UIのReact版 を使います。app/api/docs/page.tsxを作成します。

app/api/docs/page.tsx
"use client";

import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";

import openapi from "../openapi.json";

export default function ApiDocsPage() {
  const spec = JSON.stringify(openapi);
  return <SwaggerUI spec={spec} url="/api/spec" />;
}

こちらもこれだけで/api/docsにアクセスするとSwagger UIによるAPIドキュメントを確認できます。

<SwaggerUI />のpropsでspecとurlを両方渡しているのは、urlを渡すだけではホットリロードが効かないからです。
また、specを渡すだけではAPIドキュメントに定義ファイルへのリンクが表示されません。ですので両方必要と考えています。

YAML形式の場合はホットリロードはできないので、specは渡さずにurlだけ渡せば良いはずです。

認証機能を付けたい場合

/api/docs/api/specも、どちらもNext.jsの純粋なAPIとページなので他のページと同様に認証をかけたりできます。

ホットリロード

定義ファイルをJSON形式で作っていてimport構文を使って読み込んでいる場合に限り、ホットリロードが効きます。
ファイルを変更した際に /api/docsのドキュメントの内容が即座に更新されます。

おわり

小規模なプロジェクトであればこれだけで十分にAPIドキュメントをホストできると思います。試してみてください。