OpenAPI ファイルを 分割 / 結合 する 方法

0 件のコメント

今回は「OpenAPI の ファイル を 分割/結合 する方法」についてまとめます。

OpenAPIは普通に記述しているとどうしても肥大化してしまいます。 なので、どこかのタイミングでファイル分割を検討することになります。 今回はその「ファイル分割/結合」の方法についてまとめました。

元にするOpenAPI

今回は OpenAPI でよく出てくる Swagger Petstore のAPIを利用してファイル分割、結合をやってみます。 Swagger PetstoreGitHub OAI / OpenAPI-Specification で取得できます。 以下に断面は記載しておきます(コードは閉じているので開くと確認できます)。

ファイル分割

ファイル分割でポイントになるのは $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 の フォロー」 お願いします!!