背景
初投稿です。イレブンナインの松田です。@matsudachikara2
最近、社内でAPIの仕様をどうやって管理、共有していくかを検討してました。そこで、Swaggerを使うのがいい感じらしい!ということを聞き、調査を始めましたが、個々のツールの使い方や導入は出てくるものの、具体的にチームで共有、管理まではどうやってするのかいまいち分かりませんでした。
調べていくとSwaggerHubなどのプラットフォームを使うのが一般的みたいでしたが、もっと簡単にSwagger EditorとSwagger UIとSwaggerのモックAPIサーバーを使えたらなということで作ってみました。
Swaggerとは?
こちらはとても良い記事がすでにありますので、そちらを見ると良いと思います!
公開リポジトリ
swagger-all-in-one-docker-container
概要
Swagger EditorとSwagger UIとSwaggerのモックAPIサーバー(openapi: 3.x)を手軽に同時に環境に立ち上げられるようdocker-compose化してみました
もしswagger specをswagger: "2.0"
形式で書きたい場合はswagger2.0
branchをお使いください
このコンテナには初期でサンプルのswagger specが入っていて、editor, ui, api, nginxが初期状態で立ち上がり、最初から設定無しで起動出来るようになってます
あとはEditorでopenapi.jsonを保存しコンテナを立ち上げ直すだけで、UIとモックAPIサーバーを最新に更新していくことが出来ます
起動方法
docker-compose up -d
こんな感じで起動します
docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------
swagger-api /usr/local/bin/apisprout / ... Up 0.0.0.0:8083->8000/tcp
swagger-editor sh /usr/share/nginx/docker ... Up 0.0.0.0:8081->8080/tcp
swagger-nginx nginx -g daemon off; Up 80/tcp, 0.0.0.0:8084->8084/tcp
swagger-ui sh /usr/share/nginx/docker ... Up 0.0.0.0:8082->8080/tcp
使い方
- swagger-editorでswagger specを編集
- swagger specをjson形式でswagger-editorの画面から保存
- 保存したjsonを
swagger/openapi.json
に移動 -
docker-compose restart
でswagger-uiとswagger-api(mock server)に変更が反映される - もしswagger-editorで外部ファイルを読み込みたい場合は、画面内
File > Import File
から読み込む
注意
-
http://localhost:8082/
で参照するとキャッシュで変更が反映されない場合があるのでhttp://127.0.0.1:8082/
で参照した方が良い(apiも同様) - swagger-apiの起動に失敗した場合は、
swagger/openapi.json
からモックAPIの立ち上げに失敗した可能性が高いので、docker logs
などでデバッグし、openapi.jsonを直してから立ち上げ直す - swagger-apiを他ドメインからアクセスしたい場合は(CORS対策)、swagger-nginx経由でswagger-apiにアクセスする
swagger-editor
- swagger specを編集出来る
- swagger specはjson, yaml形式などにしてエクスポート出来て、swagger-uiから参照するとドキュメントとして見れる。swagger-apiからjsonを参照するとモックAPIサーバーになる
swagger-ui
- swagger specをドキュメントとして見れる
- swagger specは環境変数でjsonファイルまたは、API_URLからjsonを参照できる
environment:
SWAGGER_JSON: /openapi.json
# API_URL: ""
- このレポジトリの./swagger/openapi.jsonが参照先になっている
swagger-api(apisprout)
- 内部的にapisproutを使用しています
- swagger specは
openapi: 3.x
に対応しています - こちらも./swagger/openapi.jsonが参照先になっている
- ただしapisproutがヘッダーに
Access-Control-Allow-Origin
を付けてくれないので、前段にnginxを置き、ヘッダーを付与してAPIにプロキシしています。(他ドメインからAPIにアクセスできないと不便なので。CORS対策。)
swagger-nginx
-
ヘッダー修正用に配置
-
8084
portでnginx経由でモックAPI(swagger-api)にアクセス出来ます。 -
curl等で叩けます
* 例 curl -i -X GET http://127.0.0.1:8084/pets/1 -H "accept: application/json" HTTP/1.1 200 OK Server: nginx/1.15.3 Date: Thu, 04 Oct 2018 07:58:19 GMT Content-Type: application/json Content-Length: 49 Connection: keep-alive Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, PATCH, DELETE, PUT, OPTIONS Access-Control-Allow-Headers: Origin, Authorization, Accept Access-Control-Allow-Credentials: true { "id": 1, "name": "doggie", "tag": "dog" }
追記
2018/08/01
swagger specの記述をswagger: "2.0"
からopenapi": "3.x"
に変更しました。
理由としては、自社で実際にswagger specを作成、編集してみてopenapi": "3.x"
の方が、圧倒的に書きやすかった為です。
それに合わせてmock apiのコンテナの中身を変更、docker-compose.yml等も修正しました。
注意としては、mock apiのみopenapi": "3.x"記述方式でしか動かなくなっております。
もしswagger: "2.0"
形式で記述したい場合はswagger2.0
ブランチを用意したのでそちらからご使用ください。
2018/10/04
他ドメインからAPIにアクセスできないと不便なので(CORS対策)、nginxのコンテナを追加しました。
apisproutがヘッダーにAccess-Control-Allow-Origin
を付けてくれないので、前段にnginxを置き、ヘッダーを付与してAPIにプロキシしています。
8084
portでnginx経由でモックAPIにアクセス出来ます。
SNSが苦手ということでリンクしませんが、木梨さんというスーパーエンジニアの方にサクッと直してもらいました。 Special Thanks to Kinashi!
変更前
$ curl -i -X GET http://127.0.0.1:8083/pets/1 -H "accept: application/json"
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 04 Oct 2018 07:36:15 GMT
Content-Length: 49
{
"id": 1,
"name": "doggie",
"tag": "dog"
}
変更後
$ curl -i -X GET http://127.0.0.1:8084/pets/1 -H "accept: application/json"
HTTP/1.1 200 OK
Server: nginx/1.15.3
Date: Thu, 04 Oct 2018 07:36:18 GMT
Content-Type: application/json
Content-Length: 49
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, PATCH, DELETE, PUT, OPTIONS
Access-Control-Allow-Headers: Origin, Authorization, Accept
Access-Control-Allow-Credentials: true
{
"id": 1,
"name": "doggie",
"tag": "dog"
}