やりたいこと
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