今回は「OpenAPI の ファイル を 分割/結合 する方法」についてまとめます。
OpenAPIは普通に記述しているとどうしても肥大化してしまいます。 なので、どこかのタイミングでファイル分割を検討することになります。 今回はその「ファイル分割/結合」の方法についてまとめました。
元にするOpenAPI
今回は OpenAPI でよく出てくる Swagger Petstore のAPIを利用してファイル分割、結合をやってみます。
Swagger Petstore は GitHub OAI / OpenAPI-Specification で取得できます。
以下に断面は記載しておきます(コードは閉じているので開くと確認できます)。
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
ファイル分割
ファイル分割でポイントになるのは $ref を用いたオブジェクト参照です。
その記述方法は HTML のハイパーリンクに似ています。
$ref の記述方法は以下のような2パターンを覚えておけばOKです。
-
同一ファイル内の別オブジェクトを参照
$ref: "#/components/schemas/Pet"
"#"(ハッシュ)に続けてファイル内のオブジェクトパスを指定します。 -
別ファイルのオブジェクトを参照
$ref: "./schemas.yaml"
現在のファイルから見た相対パスでファイル指定します。
では、前述の $ref オブジェクト参照 はどこでも使えるかというと…使える場所が限定されています。
どこで使えるかの詳細はリファレンスを参照になりますが…主要なものは以下の箇所になります。
- paths/{path}
- components/schemas
- components/responses
- components/parameters
- components/examples
- components/requestBodies
- components/headers
- components/securitySchemes
では、上記を参考にしながらさっそくファイル分割を行っていきましょう。
分割後のフォルダ/ファイル構成
分割後のファイル構成は以下のようになります。 順にどのように記述するか見ていきましょう。
<ROOT>
│ openapi.yaml
│
├─paths
│ pets.petid.yaml
│ pets.yaml
│
└─schemas
Error.yaml
index.yaml
Pet.yaml
Pets.yaml
分割後のファイル
ファイル分割のポイントは $ref です。
$ref は指定したファイルからの相対パスで指定します。
ルートドキュメント ( openapi.yaml ) からのパスではない点に注意です。
/openapi.yaml
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
"/pets":
$ref: "./paths/pets.yaml"
"/pets/{petId}":
$ref: "./paths/pets.petid.yaml"
components:
schemas:
$ref: "./schemas/index.yaml"
できるだけ上位のオブジェクトで分割を行います。
paths 直下から分割しているブログも見かけたりしますが…
一応 OpenAPI 仕様的にはNGです。
/schemas/index.yaml
Pet: $ref: "./Pet.yaml" Pets: $ref: "./Pets.yaml" Error: $ref: "./Error.yaml"
schemas は直下がオブジェクト参照にできるので、上記のように index.yaml を作成するとわかりやすいと思います。
中身はすべて子要素(=実態となるオブジェクト)を記載します。
/schemas/Pet.yaml
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
/schemas/Pets.yaml
type: array items: $ref: "./Pet.yaml"
Pets は配列で子要素に Pet を利用します。
Pet は同じ兄弟フォルダにファイルが存在するのでオブジェクト参照も同一ディレクトリとして相対パスで参照します。
/schemas/Error.yaml
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
/paths/pets.yaml
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "../schemas/Pets.yaml"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "../schemas/Error.yaml"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "../schemas/Error.yaml"
schemas を参照したい場合、相対パスだと1つ上のフォルダへ上がる必要があるため、上記のように ../schemas/XXX という表現になります。
/paths/pets.petid.yaml
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "../schemas/Pet.yaml"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "../schemas/Error.yaml"
分割したファイルの結合
swagger-cli を利用すると分割したファイルを結合して1つにすることができます。
結合ツールのインストール
swagger-cli は Node.js のツールになるので、 npm でインストールします。 インストールは以下のコマンドで行います。
npm install -g @apidevtools/swagger-cli
結合ツールを使ってファイル結合
以下のコマンドで結合を行います。
swagger-cli bundle -o ./build/openapi.yaml -t yaml ./openapi.yaml
基本のコマンドおよびオプションは以下のような構成になっています。
swagger-cli bundle [options] <file>
- -o, --outfile <file>
- 出力先ファイル名を指定します。
- -f, --format <spaces>
- インデントのスペース数を指定します。
デフォルトは
2です。 - -t, --type <filetype>
- OpenAPIのファイルフォーマットを指定します。
指定できるのは
jsonまたはyamlです。 デフォルトはjsonです。
今回は「OpenAPI の ファイル を 分割/結合 する方法」についてまとめました。 参考になったでしょうか? 本記事がお役に立っていると嬉しいです!!
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!