2015.11.26
Swaggerで作るSPECファイルを小さいファイルに分割する
こんにちは、井上です。
「Swaggerで始めるモデルファーストなAPI開発」を見て興味を持ったので、Swaggerをちょっと触ってみたのですが、すぐに、これ1ファイルの YAMLファイルでメンテナンスするの超しんどくない?と感じました。
なので、分割する方法を調べてみました。で、みつけたのが下記エントリ。
How to split a Swagger spec into smaller files
方法としては、別々のファイルに書いた定義を $ref で参照しておき、それを json-refs でマージして1ファイルに戻すというやり方のようです。
下記のような YAML ファイルを、
swagger: '2.0'
info:
version: 0.0.0
title: Simple API
paths:
/foo:
get:
responses:
'200':
description: OK
/bar:
get:
responses:
'200':
description: OK
schema:
$ref: '#/definitions/User'
definitions:
User:
type: object
properties:
name:
type: string
下記のように分割します。
$ tree
.
├── README.md
├── definitions
│ ├── User.yaml
│ └── index.yaml
├── index.yaml
├── info
│ └── index.yaml
├── package.json
├── paths
│ ├── bar.yaml
│ ├── foo.yaml
│ └── index.yaml
└── resolve.js
起点となる index.yaml は下記のようにリンク集のような形になります。
swagger: '2.0'
info:
$ref: ./info/index.yaml
paths:
$ref: ./paths/index.yaml
definitions:
$ref: ./definitions/index.yaml
サンプルが githubに上がっているので、それで試してみます。
$ git clone https://github.com/mohsen1/multi-file-swagger-example.git
$ cd multi-file-swagger-example
$ npm install
$ node resolve.js
{
"swagger": "2.0",
"info": {
"version": "0.0.0",
"title": "Simple API"
},
"paths": {
"/foo": {
"get": {
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/bar": {
"get": {
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}
}
},
"definitions": {
"User": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
全部マージして出力されました。
JSON形式になっていますが、resolve.js を下記のような感じに変更すると、YAML 形式で出力されます。
※ js-yaml が必要なので、別途 npm install js-yaml が必要です。
var resolve = require('json-refs').resolveRefs;
var YAML = require('js-yaml');
var fs = require('fs');
var root = YAML.load(fs.readFileSync('index.yaml').toString());
var options = {
processContent: function (content) {
return YAML.load(content);
},
resolveLocalRefs: false
};
resolve(root, options).then(function (results) {
console.log(YAML.dump(results.resolved));
});
$ node build.js
swagger: '2.0'
info:
version: 0.0.0
title: Simple API
paths:
/foo:
get:
responses:
'200':
description: OK
/bar:
get:
responses:
'200':
description: OK
schema:
$ref: '#/definitions/User'
definitions:
User:
type: object
properties:
name:
type: string
オプションに、resolveLocalRefs: false を加えると、ファイル内の $ref: ‘#/definitions/User’ は展開されず、別ファイルのみ展開されます。
同じ定義を繰り返し参照しているような場合には、展開しないほうが見通しが良いと思います。
使用できるオプションは、下記で参照できます。
json-refs/API.md at master · whitlockjc/json-refs