OpenAPI は広く使われているものの、OpenAPI 仕様と公開されているスキーマファイル群の同期が取れていないという問題が存在する。その詳細を備忘録として書き残しておく。
OpenAPI 3.1.0 仕様によれば、Paths オブジェクト下で $ref
を次のように使うことは可能である。
paths:
/api/foo:
$ref: paths/api-foo.yaml
しかし、このように記述された OpenAPI 文書の有効性を、(現時点で最新とされる) 下記のスキーマファイル群と、
とあるバリデータ (json-schema-validator) を用いて確認すると (参照: Validating an OpenAPI document)、間違っていると言われてしまう。
調べたところ、どうも https://spec.openapis.org/oas/3.1/schema/2022-10-07 内の /$defs/paths
の定義↓が OpenAPI 仕様と合致していないことが原因のように思えてきた。
"paths": {
"$comment": "https://spec.openapis.org/oas/v3.1.0#paths-object",
"type": "object",
"patternProperties": {
"^/": {
"$ref": "#/$defs/path-item"
}
},
"$ref": "#/$defs/specification-extensions",
"unevaluatedProperties": false
},
"#/$defs/path-item"
となっている箇所は "#/$defs/path-item-or-reference"
であるべきなのではないか、という疑念だ。
そこで、OpenAPI コミュニティの Slack に参加して質問したところ、「その問題は PR 3355: Fix 3.1 Path Item schema により修正されたが、https://spec.openapis.org/ で公開されているスキーマファイル群は更新されていない」ということだった。
更新されていない理由は「更新作業をする人がいないから」 だそうだ。
スキーマファイル群の不具合修正や公開スキーマファイル群更新作業の内容については Issue 3715: Define and document our schema publishing process に書かれているものの、それを実行するボランティアがいない、と。
自社の新製品の API を OpenAPI で記述し、その記述自体のテストを自動化しようと作業していたところ、この問題を踏んでしまった。
もちろん、API 毎に一つの YAML を作成するという次のような書き方を諦め、
paths:
/api/foo:
$ref: paths/api-foo.yaml
かわりに、全ての API の情報を一つのファイルに含める、
paths:
/api/foo:
post:
requestBody:
content:
application/json:
schema:
$ref: components/foo-request.yaml
# 以下略
という書き方にすれば、技術的には有効性確認はできる。しかしながら、本来分割できるものを一箇所にまとめてごちゃごちゃ書くのは、美しくない。
すっきりして美しいかどうかは、品質や維持管理の容易さにとって大切なのだ。
とはいえ、OpenAPI 仕様のスキーマファイル群の不具合修正と更新作業の責任をボランティアで引き受けるほどの余裕はない。せいぜいできるのは、Issue 3715 の作業負担を多少軽減するためのスクリプトを二つ提供することくらいだ。
無害なスクリプトなのでさくっと main ブランチにマージしてもらいたいところではあるが、これらの PR をレビュー・承認・マージする作業もボランティアの方々がおこなっているので、残念ながら大きな期待はできない。マージされるとしても、長い年月がかかるだろう。そのため、当面は 2022-10-07 のスキーマ群を使わざるをえない。
追記 (2024-05-17)
「このプロジェクトでは Ruby を使ってないんだよなぁ」というコメントがあったので、シェルスクリプトバージョンを作成。