今回は「OpenAPI の ファイル を 分割/結合 する方法」についてまとめます。
OpenAPIは普通に記述しているとどうしても肥大化してしまいます。 なので、どこかのタイミングでファイル分割を検討することになります。 今回はその「ファイル分割/結合」の方法についてまとめました。
元にするOpenAPI
今回は OpenAPI でよく出てくる Swagger Petstore
のAPIを利用してファイル分割、結合をやってみます。
Swagger Petstore
は GitHub OAI / OpenAPI-Specification で取得できます。
以下に断面は記載しておきます(コードは閉じているので開くと確認できます)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | openapi: "3.0.0" info: version: 1.0.0 title: Swagger Petstore license: name: MIT servers: 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
では、上記を参考にしながらさっそくファイル分割を行っていきましょう。
分割後のフォルダ/ファイル構成
分割後のファイル構成は以下のようになります。 順にどのように記述するか見ていきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 | <ROOT> │ openapi.yaml │ ├─paths │ pets.petid.yaml │ pets.yaml │ └─schemas Error.yaml index.yaml Pet.yaml Pets.yaml |
分割後のファイル
ファイル分割のポイントは $ref
です。
$ref
は指定したファイルからの相対パスで指定します。
ルートドキュメント ( openapi.yaml
) からのパスではない点に注意です。
/openapi.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | openapi: "3.0.0" info: version: 1.0.0 title: Swagger Petstore license: name: MIT servers: 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
1 2 3 4 5 6 | Pet: $ref: "./Pet.yaml" Pets: $ref: "./Pets.yaml" Error: $ref: "./Error.yaml" |
schemas
は直下がオブジェクト参照にできるので、上記のように index.yaml
を作成するとわかりやすいと思います。
中身はすべて子要素(=実態となるオブジェクト)を記載します。
/schemas/Pet.yaml
1 2 3 4 5 6 7 8 9 10 11 12 | type: object required: - id - name properties: id: type: integer format: int64 name: type: string tag: type: string |
/schemas/Pets.yaml
1 2 3 | type: array items: $ref: "./Pet.yaml" |
Pets
は配列で子要素に Pet
を利用します。
Pet
は同じ兄弟フォルダにファイルが存在するのでオブジェクト参照も同一ディレクトリとして相対パスで参照します。
/schemas/Error.yaml
1 2 3 4 5 6 7 8 9 10 | type: object required: - code - message properties: code: type: integer format: int32 message: type: string |
/paths/pets.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 でインストールします。 インストールは以下のコマンドで行います。
1 | npm install -g @apidevtools/swagger-cli |
結合ツールを使ってファイル結合
以下のコマンドで結合を行います。
1 | swagger-cli bundle -o ./build/openapi.yaml -t yaml ./openapi.yaml |
基本のコマンドおよびオプションは以下のような構成になっています。
1 | swagger-cli bundle [options] <file> |
- -o, --outfile <file>
- 出力先ファイル名を指定します。
- -f, --format <spaces>
- インデントのスペース数を指定します。
デフォルトは
2
です。 - -t, --type <filetype>
- OpenAPIのファイルフォーマットを指定します。
指定できるのは
json
またはyaml
です。 デフォルトはjson
です。
今回は「OpenAPI の ファイル を 分割/結合 する方法」についてまとめました。 参考になったでしょうか? 本記事がお役に立っていると嬉しいです!!
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!