SwaggerをReactアプリ内に掲載したい
やりたいこと
React で GUI アプリケーションを作成していますが、API もユーザーに公開しています。
ユーザーへ公開するためのドキュメントは別管理していましたが、アプリと合わせて更新できた方が更新忘れもなくリリース対象も減るので、API リファレンスもアプリケーション内に掲載するようにします。
手間を減らすため、実装時にバックエンドと共有している OpenAPI 形式の yaml ファイルをそのまま使いたいです。
動作確認環境
パッケージ | バージョン |
---|---|
node | 22.11.0 |
yarn | 1.22.17 |
React | 18.3.1 |
vite | 6.0.1 |
Typescript | 5.6.2 |
手順
React をセットアップ
React + Vite +Typescript でプロジェクトを作成します。
プラグインをインストール
Swagger 表示プラグインである swagger-ui-react をインストールします。
$ yarn add swagger-ui-react
info Direct dependencies
└─ swagger-ui-react@5.18.2
Typescript 用に型定義もインストールします。
$ yarn add -D @types/swagger-ui-react
info Direct dependencies
└─ @types/swagger-ui-react@4.18.3
本筋ではないですが、ルーティング用に react-router-dom もインストールします。
$ yarn add react-router-dom
info Direct dependencies
└─ react-router-dom@7.0.1
実装
API 定義は OpenAPI 形式の yaml ファイルで管理されています。
このファイルを読み込んでアプリケーション内の1ページに表示します。
できあがった全体を示します。
ファイル構成
├── eslint.config.js
├── index.html
├── package.json
├── public
│ └── api
│ └── reference.yaml // 追加
├── src
│ ├── index.css
│ ├── main.tsx // 編集
│ ├── pages
│ │ └── ApiReference
│ │ └── index.tsx // 追加
│ └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── yarn.lock
public/api/reference.yaml
ここでは Swagger のサンプルコードをコピーしてきただけです。プロジェクトのファイルに差し替えてください。
openapi: 3.0.0
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users:
get:
summary: Returns a list of users.
description: Optional extended description in CommonMark or HTML.
responses:
"200": # status code
description: A JSON array of user names
content:
application/json:
schema:
type: array
items:
type: string
src/main.tsx
今回作ったページへのルーティングを追加。
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
+ import { BrowserRouter, Route, Routes } from "react-router-dom";
+ import ApiReference from "./pages/ApiReference/index.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
+ <BrowserRouter>
+ <Routes>
+ <Route path="/api-reference" element={<ApiReference />} />
+ </Routes>
+ </BrowserRouter>
</StrictMode>
);
src/pages/ApiReference/index.tsx
import React from "react";
import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";
const ApiReference: React.FC = () => {
return (
<div style={{
backgroundColor: "#fff"
}}>
<SwaggerUI url={"/api/reference.yaml"} />
</div>
);
};
export default ApiReference;
これのみだとダークモードに対応していなかったので背景白だけ入れました。
実プロジェクトではベーススタイルが設定されていると思うので、その中でレイアウトは調整してください。
MUI を使っているアプリケーション内では、特にスタイル衝突せずきれいに表示されました。
できないこと
Swagger では複数のファイルを指定したらファイル切り替えできる UI がヘッダーに表示されるのですが、このプラグインでは1ファイルしか指定することができません。
もし複数ファイルを扱いたい場合は、ファイル切り替えは自前で用意する必要があります。
まとめ
プラグインを使っただけで簡単に表示できました。
Discussion