OpenAPI 3.1.0+Redoc+DockerでAPIドキュメントを分割して管理する(Laravel)
はじめに
Laravelプロジェクト内でAPIが多くなり、APIドキュメントが肥大化して管理しにくいということで、以下のことを行ったので、共有します。
- OpenAPIのドキュメントを分割する
- 自動でファイルを検知し結合する(Docker化)
- ドキュメントの表示でRedocを導入(Docker化)
OpenAPIのドキュメントを分割する
ファイル構成
<storage/docs>
├─index.yaml //マージ元となるファイル
├─paths
│ ├─user
│ │ ├─login.yaml
│ └─ index.yaml //ルーティングの情報を書く
│
└─components
├─parameters //リクエストパラメーター用
│ ├─auth
│ │ ├─index.yaml
│ │ └─login.yaml
│ └─index.yaml //authなどフォルダー名を登録する用
│
├─responses //レスポンス用
│ └─parameters同様
└─requestBodies //リクエストボディー用
└─parameters同様
分割のやり方
OpenAPI3.1.0からpathsで$refを使った書き方ができます。
$refを使い、各フォルダーのindex.yamlに登録したcomponentsを参照しにいきます。
openapi: "3.1.0"
info:
title: APIドキュメント
version: 1.0.0
description: APIドキュメント
servers:
- url: http://localhost:8080
paths:
$ref: "./paths/index.yaml"
components:
requestBodies:
$ref: "./components/requestBodies/index.yaml"
parameters:
$ref: "./components/parameters/index.yaml"
responses:
$ref: "./components/responses/index.yaml"
tags:
- name: ユーザー
/user/login:
$ref: "./user/login.yaml"
post:
summary: ユーザーログイン
responses:
'200':
$ref: '#/components/responses/auth/operationsLogin'
'422':
$ref: '#/components/responses/common/loginError'
requestBody:
$ref: '#/components/requestBodies/auth/userLogin'
ファイルの結合と自動化とDocker化
ファイルの結合
yamlファイルの結合は、swagger-mergerというnpmのライブラリを使用します。
出力時には以前までのファイルを完全に上書きします。
swagger-mergerでのファイル結合のやり方
$ swagger-merger -i index.yaml -o swagger.yaml
説明
-iで分割したファイルの親ファイル(今回で言うindex.yaml)
-oで出力先とファイル名の設定をする
ファイルの結合の自動化
ファイルの変更を検知し、検知したらファイルを結合するようにします。
ファイルの変更の検知はgazeというnpmのライブラリを使用します。
以下のスクリプトでは、./storage/docs/のファイル内で変更を検知したら、yamlファイルを結合するようになっています。
const gaze = require("gaze"); // 先程のライブラリ
const path = require("path");
const merger = require("swagger-merger");
//ファイルを検知するフォルダを指定
const resolve_path = (dir) => path.join("./storage/docs/", dir);
gaze(
["index.yml", "paths/**/*", "components/**/*"],//検知するファイルを指定
{ cwd: resolve_path("") },
(_, watcher) => {
watcher.on("all", () => {
merger({
input: resolve_path("index.yml"),
output: "./storage/api-docs/api-docs.yaml",//ファイルの出力先
})
.then(() => console.log("merge!")) // マージしたときに叫びます
.catch((err) => console.error(err));
});
}
);
ファイル結合のDocker化
今までのファイル検知とファイル結合をDocker化して別コンテナとして管理します。
<storage/docs>
├─docker
│ ├─swagger
│ ├─Dockerfile
│
├─docker-compose.yml
│
└─project
└─swagger-merge.js //先ほどのファイル変更を検知して自動で結合するスクリプト
FROM node:16-slim
WORKDIR /usr/src/app
RUN npm install --location=global gaze swagger-merger
ENV NODE_PATH "/usr/local/lib/node_modules"
CMD node swagger-merge.js
version: '3'
//省略
swagger:
build: ./docker/swagger
volumes:
- ./project:/usr/src/app
tty: true
ドキュメントの表示
Redocの導入
swaggerはOpenAPI3.1.0に対応していなく、UIも良いため、Redocを使用しました。
Redocでは、OpenAPIで書かれたyamlファイルをHTMLファイルに変換してドキュメントとして読める状態にしてくれます。
導入は簡単で、redoc-cliをインストールして、コマンドを叩くだけです。
# cliをインストール
$ npm i -g redoc-cli
# swagger.yamlをもとに、/publicにapi-docs.htmlとしてHTMLを作成する
$ redoc-cli bundle swagger.yaml -o /public/api-docs.html
RedocのDocker化
以下のサンプルでは、/var/app/storage/api-docs/api-docs.yamlのファイルを監視して、
変更があれば、/var/app/public/api-docs.htmlにHTMLを書き出すようになています。
FROM node:18.3.0-slim
RUN npm install --location=global redoc-cli watch-cli
CMD ["redoc-cli"]
version: '3'
//省略
redoc:
build: ./docker/redoc
tty: true
command: >
watch -p /var/app/storage/api-docs/api-docs.yaml -c "redoc-cli build /var/app/storage/api-docs/api-docs.yaml -o /var/app/public/api-docs.html"
volumes:
- ./project/:/var/app
終わりに
ファイルの自動結合のDocker化の時に、tty: trueにして、永続化しないとダメなことに気づくまでかなり時間がかかりました、、
ドキュメントを書くときに、Stoplight StudioやSwagger Editorを使用できなくなることが唯一の欠点です。(OpenAPI3.0.0の場合、使用できます)
ので、SwaggerがOpenAPI3.1.0に対応して欲しいです。
指摘点などありましたら、コメントいただけると幸いです。
Discussion