はじめに
こんにちは!EggsPassチームで主にバックエンドエンジニアをしている徐です。 本記事では、APIドキュメントジェネレータを Swagger v2 から v3 へ移行した経緯と方法 を紹介します。
背景
プロジェクトで使用している API ドキュメントジェネレータ Swagger v2 は、長期間の運用を経て Node.js のバージョンアップや依存ライブラリの廃止などの影響を受けるようになりました。
技術的な問題
- Node.js のバージョンアップに対応できない
- 依存ライブラリが廃止されている
実務上の影響
- 新しいメンバーのPCでローカル環境を構築できない
- Swaggerの更新作業を、一部の環境を構築済みのメンバーしか行えない
これらの問題を解決するため、Swagger v2 の更新を諦め、v3 へ全面的に作り直すことにしました。本記事ではその手順を解説します。
Swaggerとは
APIドキュメントジェネレータの一つとして、特にREST APIを設計・ドキュメント化・テスト・共有するためのオープンソースフレームワーク です。
Swagger v2 と v3 の主な違い(移行時のポイント)
1.デフォルト機能でタグ参照ができない問題
Swagger v2 では、統合機能により、メインの index.yaml ファイルで tagsやpaths単位でファイルを分けて再利用することが可能でした。 例えば、以下のように別ファイルに分けたものを、メインの index.yaml で読み込むだけで参照できます。
swagger/index.yml
- name: 'Service Alpha'
description: '(Dummy) Alpha API swagger: ✅ 実装: ✅'
- name: 'Service Beta'
description: '(Dummy) Beta API swagger: ✅ 実装: ✅'
- name: 'Service Gamma'
description: '(Dummy) Gamma API swagger: ✅ 実装: ✅'
- name: 'Service Delta'
description: '(Dummy) Delta API swagger: ✅ 実装: ✅'
- name: 'Service Epsilon'
description: '(Dummy) Epsilon API swagger: ✅ 実装: ✅'
swagger/index.yml
tags:
$ref: ./swagger/tags.yml
paths:
$ref: ./swagger/paths/index.yml
definitions:
$ref: ./swagger/definitions/index.yml
responses:
$ref: ./swagger/responses/index.yml
securityDefinitions:
$ref: ./swagger/security/index.yml
v2 のように tagsやpaths を別ファイルに分けてメインの index.yaml から参照することができません。 そのため、v3 に移行する場合は、従来の分割ファイルの内容を すべて index.yaml にまとめて記述する必要 があります。
swagger/index.yml
...
tags:
- name: 'Service Alpha'
description: '(Dummy) Alpha API swagger: ✅ 実装: ✅'
- name: 'Service Beta'
description: '(Dummy) Beta API swagger: ✅ 実装: ✅'
- name: 'Service Gamma'
description: '(Dummy) Gamma API swagger: ✅ 実装: ✅'
- name: 'Service Delta'
description: '(Dummy) Delta API swagger: ✅ 実装: ✅'
- name: 'Service Epsilon'
description: '(Dummy) Epsilon API swagger: ✅ 実装: ✅'
paths:
/dummy/endpoint1:
$ref: ./paths/dummy1/post.yml
# ダミーAPI
/dummy/endpoint2:
$ref: ./paths/dummy2/post.yml
/dummy/endpoint3:
$ref: ./paths/dummy3/post_v2.yml
...
2.responses では 必ず content とメディアタイプ(例: application/json)を明示 する必要がある
Swagger v2
/get.yml
responses:
200:
description: OK
schema:
type: object
required:
- data
Swagger v3
/get.yml
responses:
200:
description: OK
content: ← ここを追加
application/json: ← ここを追加
schema:
type: object
required:
- data
3.一部の内部参照にはまだ対応していません
Swagger v2では、下記のように、401のファイルに関係なく # を使って内部参照が可能です。
/get.yml
401:
$ref: '#/responses/401'
403:
$ref: '#/responses/403'
Swagger v3では内部参照に対応していないため、相対参照で指定する形になります。
/get.yml
401:
$ref: '../../components/responses/error/401.yml'
403:
$ref: '../../components/responses/error/403.yml'
その他
1.環境依存の排除(docker-compose.yml 利用)
・docker-compose.yml を用いることで、OS やPC環境に依存せず、誰でも同一の開発環境を構築可能 ・環境構築手順をコード化することで、セットアップ時間を短縮し、チーム全員で一貫した環境を共有可能
Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY ./package.json /app/package.json
RUN yarn install
docker-compose.yml
version: '3'
services:
dsp-swagger-ui:
image: swaggerapi/swagger-ui
container_name: dsp-swagger-ui
ports:
- 8092:8080
volumes:
- ./docs:/usr/share/nginx/html
swagger-watch:
build: ./swagger-watch
volumes:
- ./swagger-watch:/app
- /app/node_modules
- ./src:/src
- ./docs/dsp-swagger.yml:/docs/dsp-swagger.yml
working_dir: /app
command: 'node index.js'
2.無料のホスティングサービスへの移行
Swagger v2ではAWSを利用していましたが、Swagger自体の更新頻度がそれほど高くないため、料金は大きくかかっていませんでした。 しかし、移行のタイミングで無料枠を活用できることと、API仕様書が開発内部しか閲覧できない点を踏まえ、要件に合った静的サイトの無料ホスティングサービスである GitHub Pages を利用することにしました。
.github/workflows/deploy.yml
name: Deploy to GitHub Pages
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: List files in current directory
run: ls -R
- name: Install swagger-cli
run: |
npm install -g swagger-cli
- name: Generate Swagger UI
uses: Legion2/swagger-ui-action@v1
with:
output: swagger-ui
spec-file: docs/dsp-swagger.yml
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: swagger-ui
GitHub Pagesの設定

まとめ
今回の移行では、Swagger v2 から Swagger v3 への直接アップグレードは、環境依存やライブラリの影響でうまくいかず、調査に時間を要しました。そのため、Swagger v2 の更新をやめ、Swagger v3 に作り直すことを決断しました。 完全に作り直す形となり、さらに v2 時代のファイルは仕様変更もあったため、そのままコピーして流用することはできませんでした。時間はかかりましたが、やりたいことを実現できたため、結果的に良い判断だったと考えています。 直接アップグレードが難航する場合は、作り直す方が適しているケースもあるかもしれません。
徐杉