肥大化したOpenAPI YAMLファイルの分割と運用方法
長年のこと多くの人によって編集に編集を重ねた結果、
数千行にも膨らんでしまったYAMLファイルを分割し、整理してみた話です。
フォルダ構成
セクションごとにフォルダを分け、
pathsセクションに関しては更にタグごとにフォルダを分けています。
フォルダ構成を以下の通りに変更しました。
改善前
改修前はもちろん単一ファイルです。これだけ見るとシンプルですね。
中身は恐ろしいですが🤮
openapi.yaml
改善後
「info」や「paths」などセクション単位でフォルダを分けて管理するようにしてみました。
src
├── root.yaml
├── info
│ └── info.yaml
├── paths
│ ├── groups
│ │ ├── groups.yaml
│ │ └── {group_id}.yaml
│ ...
│ └── users
│ ├── users.yaml
│ └── {user_id}.yaml
├── security
│ └── security.yaml
├── servers
│ └── servers.yaml
├── tags
│ └── tags.yaml
└── components
├── components.yaml
├── parameters.yaml
├── responses.yaml
├── schemas.yaml
└── securitySchemes.yaml
ファイル内容
主要なファイルを紹介します。
openapi: "3.0.0"
info:
version: "1.0.0"
title: Test REST API
contact:
name: 株式会社Miko
description:
hogehoge
servers:
$ref: "./servers/servers.yaml"
security:
$ref: "./security/security.yaml"
tags:
$ref: "./tags/tags.yaml"
paths:
$ref: "./paths/paths.yaml"
components:
$ref: "./components/components.yaml"
/v1/documents:
$ref: "./documents/documents.yaml"
/v1/documents/{document_id}:
$ref: "./documents/{document_id}.yaml"
....
post:
summary: Testhoge
operationId: document
tags:
- Document
requestBody:
description: |
hogeoge
content:
application/json:
schema:
required:
- document
allOf:
- $ref: "../../components/schemas.yaml#/DocumentHoge"
- type: object
properties:
action:
description: Foo.
type: string
example: draft
- $ref: "../../components/schemas.yaml#/Document"
...
分割ファイルとのリンク方法
分割したファイルをリンクするには、root.yaml
に書かれているように、
パス指定することでリンク可能です。
$ref: './paths/paths.yaml'
また、分割したファイルで宣言しているコンポーネントを参照する場合には、
パス指定と「#/{コンポーネント名}」を組み合わせることで可能です。
$ref: '../../components/schemas.yaml#/DocumentHoge'
ファイル統合の準備
Redoclyを利用して、ファイルを統合します。
以下のコマンドで、Redoclyをインストールします。
npm i -g @redocly/cli@latest
最初はswagger-cliを利用しようかと考えていましたが、
非推奨となっていたため、Redoclyを利用することにしました。
Redoclyを使用してできること
プレビュー機能
プレビュー用のサーバーを起動し、http://127.0.0.1:8080
へアクセスすることで、
OpenAPI ドキュメントをプレビュー表示ができます。
これで内容を確認しつつ、ファイルを編集できるため、とても便利です。
redocly preview-docs root.yaml
実際のプレビュー表示画面は、以下のDEMOページにて確認できます。
Lint
lintによる構文チェックも可能です。
(分割前のYAMLファイルで実行したところ、数件のエラーを検出したのは内緒です。)
redocly lint root.yaml
未使用なコンポーネントや型の不一致などを把握できるため、
YAMLファイルの品質を向上できます。
[1] components/schemas.yaml:50:1 at #/HogeFoo
Component: "HogeFoo" is never used.
分割が正しくできているか不安だったため、
Lintコマンドが用意されていて助かりました😮💨
ファイル統合
bundleコマンドを利用して、統合したファイルの出力が可能です。
redocly bundle root.yaml -o openapi.yaml
考慮・改善事項
pathsフォルダ内の構成
仮にhttps://hogehoge.com/api/v1/documents/hoge/foo/bar/
というエンドポイントがあった時、
どのようにフォルダ構成を考えるでしょうか?
単一ファイルで管理するのであれば、何も考えずに済む話ですが、
分割するとなると特にpathsセクション内ではファイル数が多くなったため、
フォルダ構成について2つの方法を考えていました。
- パスの階層ごとにフォルダを作成する
- ファイル名に全てを委ねる
1. パスの階層ごとにフォルダを作成する
パスの通りにフォルダを作成し、最下層のパスがファイル名になる方法です。
# documents/hoge/foo/bar
documents
└── hoge
└── foo
└── bar.yaml
2. ファイル名に全てを委ねる
こちらは、パスに含まれる「/」を「_」に置換するだけの方法です。
# documents/hoge/foo/bar
documents
└── hoge_foo_bar.yaml
最終的には「2. ファイル名に全てを委ねる」を選びました。
理由としては、1の場合だとフォルダ階層が深くなるほど、ファイル内に記載する相対パスが長くなるためです。
$ref: '../../../../../../components/schemas.yaml#/DocumentHoge'
全体構成
記事にまとめつつ、まだまだフォルダ構成について最適化できてないなと感じたので、
少しずつ改善を進めていく予定です。
Discussion