APIドキュメントとスタブをまとめて管理できる環境を作りました。
やりたいこと
フロントエンドとバックエンドの認識合わせ、及び開発のため、APIの定義が存在するファイルはフロントエンドとバックエンドが共有するリポジトリに載せておきたいです。
そこで、APIの定義にはSwaggerを使うとします。
この場合、下記を全て実現できると幸せになれると感じました。
- SwaggerをSwagger Editorを使ってAPI定義を書きたい
- Swagger UIでAPI定義を見たい
- 作ったSwaggerファイルから、自動生成されたレスポンスを返してくれるスタブが欲しい
ということで、これらを実現する環境をDockerを使って構築していきたいと思います。
Dockerを使えば環境構築も一瞬で終わりますし、スタブの再生成もコンテナをビルドするだけで行えるので、それぞれ相性が良いです。
構成
- API作成 & 編集: Swagger Editor
公式ページ: https://swagger.io/docs/open-source-tools/swagger-editor/ - APIドキュメント閲覧: Swagger UI
公式ページ: https://swagger.io/docs/open-source-tools/swagger-ui - スタブサーバー生成: Swagger Codegen
公式ページ: https://swagger.io/docs/open-source-tools/swagger-codegen/
ソース
ディレクトリ構成
.
├── docker/
│ └── stub/
│ └── Dockerfile # スタブ用Dockerfile
├── swagger/ # swagger関連のソース用ディレクトリ
│ ├── stub/ # swagger.yamlから自動生成されたスタブのソース
│ │ ├── index.js
│ │ ├── ...
│ │ └── ...
│ └── swagger.yaml # API定義ファイル
└── Makefile # 各種コマンド管理
Swagger Editorを使ってAPI定義ファイルであるswagger.yamlを生成し、そのファイルを元にスタブに設置するファイル及び、スタブコンテナをビルドします。
Makefile
ビルドコマンドや各種サーバー起動コマンドの定義です。
IMAGE_STUB=api_stub
PORT_SWAGGER_EDITOR=8081
PORT_SWAGGER_UI=8082
PORT_STUB=8080
SWAGGER_DIR_PATH=$(PWD)/swagger
SWAGGER_YAML_PATH=${SWAGGER_DIR_PATH}/swagger.yaml
# swagger.yamlからスタブ用ソース及びスタブコンテナをビルドする
.PHONY: build_stub
build_stub:
@echo "=== Generating stub file from swagger.yaml is running... ==="
docker run --rm \
-v ${SWAGGER_DIR_PATH}:/swagger \
swaggerapi/swagger-codegen-cli generate \
-l nodejs-server \
-i /swagger/swagger.yaml \
-o /swagger/stub
@echo "=== Generating stub file is completed. ===\n"
@echo "=== Building new container... ==="
docker build -f docker/stub/Dockerfile -t ${IMAGE_STUB} .
@echo "=== Building container is completed. ==="
# スタブを起動
.PHONY: run_stub
run_stub:
docker run --rm -p ${PORT_STUB}:8000 ${IMAGE_STUB}
# Swagger Editor用サーバーを起動
.PHONY: run_swagger_editor
run_swagger_editor:
docker run --rm -p ${PORT_SWAGGER_EDITOR}:8080 swaggerapi/swagger-editor
# Swagger UI用サーバーを起動
.PHONY: run_swagger_ui
run_swagger_ui:
docker run --rm -p ${PORT_SWAGGER_UI}:8080 \
-v ${SWAGGER_YAML_PATH}:/usr/share/nginx/html/api/swagger.yaml \
-e API_URL=http://localhost:${PORT_SWAGGER_UI}/api/swagger.yaml \
swaggerapi/swagger-ui
docker/stub/Dockerfile
Node.jsでホスティングをするだけのシンプルなサーバーです。
FROM node:13.7.0-alpine3.10
ENV APP_HOME /usr/src/app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
# スタブ用ソースをコンテナにコピー
COPY swagger/stub/ $APP_HOME
EXPOSE 8000
RUN npm install
ENTRYPOINT ["npm", "start"]
使ってみる
ステップ1: Swagger Editor
まずは、$ make run_swagger_editor
コマンドでSwagger Editorを起動します。
http://localhost:8081
にアクセス。
Swagger Editor上で、 GET /persons
APIを定義。
swagger: '2.0'
info:
version: 1.0.0
title: Swagger-sample
description: |
#### サンプル
schemes:
- http
host: localhost:8080
basePath: /api/v1
paths:
/persons:
get:
summary: Get all persons.
parameters: []
responses:
200:
description: A JSON array of person model
schema:
type: array
items:
$ref: '#/definitions/Person'
example:
- id: 1
name: Mike
age: 23
- id: 2
name: Jun
age: 20
- id: 3
name: Jack
age: 26
definitions:
Person:
type: object
properties:
id:
type: integer
name:
type: string
age:
type: integer
Swagger Editor上の Save as YAML
をクリックし、ダウンロードされたswagger.yamlをswaggerディレクトリ配下へ移動。
$ cp ~/Download/swagger.yaml ./swagger
ステープ2: Swagger UIでAPIを確認
$ make run_swagger_ui
コマンドで、Swagger UIを起動します。
http://localhost:8082
にアクセス。
すると、先ほど作成したAPIがSwagger UI上で表示されることを確認できます。
ここまでで、Swaggerを管理する環境はできました。
それでは、本題のスタブの用意へと移りましょう。
ステップ3: スタブコンテナビルド
$ make build_stub
でスタブコンテナをビルド。
Building container is completed.
が表示されれば完了です。
なお、ここでは下記の順でビルドが行われます。
- スタブ用ソースを自動生成
- 自動生成されたソースがパッケージングされたコンテナをビルド
ステップ4: スタブを使用してAPIを呼び出す
$ make run_stub
でスタブコンテナを起動。
まず、http://localhost:8080/docs
へアクセスすると、先ほど定義したAPIがドキュメントとして表示されます。
では、http://localhost:8080/api/v1/persons
へアクセスしてみましょう。
すると、SwaggerファイルにてExampleで定義したレスポンスが返ってくることが確認できます。
これで、Swaggerファイルで定義したレスポンスからスタブを自動生成し、呼び出せることが確認できました!
まとめ
Swagger Editorでswagger.yamlを作成し、それをSwagger UIで確認、及び定義したAPIのレスポンスを返すスタブに変換し呼び出せる環境を構築しました。
APIを開発するのであればAPIドキュメントは必須ですし、さらにそのAPIを開発中にフロントエンド側で使いたいとなるとスタブの開発は不可欠です。
スタブの自動生成を使用すれば、APIとスタブの二重管理などの手間も省けます。
しばらく使ってみて、また知見があれば記録を残そうと思います。
補足
Swagger Editorで編集したファイルをダウンロードしてswaggerディレクトリ配下に設置するところのみ、手動のオペレーションが発生してしまっています。
ここに関して自動化させられるやり方をご存じの方がいらっしゃいましたら、アドバイスをいただけますと嬉しいです m(__)m