Committee + Open APIでYAMLファイルを分割する 2021年夏版

やりたいこと

OpenAPIでAPIを定義したいが、ファイルを分割して管理したい

バージョン

  • Committee 4.0.0(committee-rail 0.5.1)
  • Open API 3.0.3

最初にやったこと&課題

Open APIの仕様に則ってAPIを(ここではopenapi.yamlとした)を定義した

openapi: 3.0.3
info:
  title: Title
  description: Title
  version: 1.0.1
servers:
  - url: 'http://localhost'
paths:
  /api/token:
    get:
      description: get access token
      responses:
        200:
          description: success
          content:
            application/json:
              schema:
                type: object
                required:
                  - token
                example: { token: 'access token' }
                properties:
                  token:
                    type: string

RailsのRequestSpecはこんな感じ

require 'rails_helper'

RSpec.describe 'Api::Token', type: :request do
  include Committee::Rails::Test::Methods

  it 'GET /token' do
    get api_token_path

    expect(response).to have_http_status 200
    assert_response_schema_confirm 200
  end
end

かんたんな文字列を返すAPIを定義した。ただこれだとみんなで触るときにコンフリクトとかが頻発するのでわけたい。

ファイルを分割する

$ref というのがOpenAPIに定義されているので、それが使えそう。$ref の使い方のドキュメントを読むとpaths直下には入れられないので、get以降を切り出す。

openapi.yaml

openapi: 3.0.3
info:
  title: Title
  description: Title
  version: 1.0.1
servers:
  - url: 'http://localhost'
paths:
  /api/token:
    $ref: 'token.yaml'

token.yaml

get:
  description: get access token
  responses:
    200:
      description: success
      content:
        application/json:
          schema:
            type: object
            required:
              - token
            example: { token: 'access token' }
            properties:
              token:
                type: string

これでテストを実行すると以下のようなエラーが出て怒られる。redoc からHTMLを生成するときちんと生成されるのが余計にわからん...

NoMethodError: undefined method `set_path_item_to_operation' for #

  0) Api::Token GET /token
     Failure/Error: assert_response_schema_confirm 200

     NoMethodError:
       undefined method `set_path_item_to_operation' for #

エラーを読んでみる

set_path_item_to_operation for # なので、path itemが足りない?となってドキュメント読んだりしてた。

結論

pathsとURLを分割先のファイルに記載して書けばよかった。ドキュメントや探してみてもCommitteeのIssuesを見ても特にチケット上がってなかったのでよくわからんが動いた

openapi.yaml

openapi: 3.0.3
info:
  title: Title
  description: Title
  version: 1.0.1
servers:
  - url: 'http://localhost'
paths:
  /api/token:
    # ~1は`/` のエスケープ
    $ref: './token.yaml#/paths/~1api~1token'

token.yaml

paths:
  /api/token:
    get:
      description: get access token
      responses:
        200:
          description: success
          content:
            application/json:
              schema:
                type: object
                required:
                  - token
                example: { token: 'access token' }
                properties:
                  token:
                    type: string