肥大化したOpenAPI YAMLファイルの分割と運用方法

2024/12/04に公開

長年のこと多くの人によって編集に編集を重ねた結果、
数千行にも膨らんでしまった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

ファイル内容

主要なファイルを紹介します。

root.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"
paths/paths.yaml
/v1/documents:
  $ref: "./documents/documents.yaml"

/v1/documents/{document_id}:
  $ref: "./documents/{document_id}.yaml"

....
paths/documents/documents.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を利用して、ファイルを統合します。
https://github.com/Redocly/redoc

以下のコマンドで、Redoclyをインストールします。

npm i -g @redocly/cli@latest

最初はswagger-cliを利用しようかと考えていましたが、
非推奨となっていたため、Redoclyを利用することにしました。
https://github.com/APIDevTools/swagger-cli

Redoclyを使用してできること

プレビュー機能

プレビュー用のサーバーを起動し、http://127.0.0.1:8080へアクセスすることで、
OpenAPI ドキュメントをプレビュー表示ができます。
これで内容を確認しつつ、ファイルを編集できるため、とても便利です。

redocly preview-docs root.yaml

実際のプレビュー表示画面は、以下のDEMOページにて確認できます。
https://redocly.github.io/redoc/

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. パスの階層ごとにフォルダを作成する
  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'

全体構成

記事にまとめつつ、まだまだフォルダ構成について最適化できてないなと感じたので、
少しずつ改善を進めていく予定です。

コラボスタイル Developers

Discussion