2023年9月10日日曜日

OpenAPIソースファイルの分割

 大規模なウェブサービスを作っていると、WebAPIの数も膨大になってきます。APIのドキュメントを作成するためにOpenAPIを使っている人も多いと思いますが、APIの数が増えてくるとドキュメントのソースファイル(JSON/YAML)が大きくなり、編集しづらくなります。

でかいソースファイルは分割するのが世の常で、もちろんOpenAPIにもソースファイルを分割できる仕様はあるのですが(文法はJSON Schemaなので)、問題は分割したファイル($refによる参照先のファイル)にIDEのコード補完が利かなくなることです。

そこで、ソースファイルを分割しつつ、IDEのコード補完も利かせる方法を考えてみます。IDEはウェブ開発の定番Visual Studio Codeを想定します。え?VSCodeはIDEじゃない?気にするな。

なお、この記事は「OpenAPIのドキュメントの書き方を知っていること」「ソースファイルの分割方法($ref)を知っていること」「VSCodeのOpenAPI拡張機能を使っていること」を前提としています。その上で、分割したファイルの補完を使う方法の説明です。

VSCodeの補完の仕組み

そもそもなぜ分割したファイルに補完が利かないかというと、当たり前ですがVSCodeから見たら分割後のファイルは単なるYAMLファイルであって、OpenAPIのソースコードという情報が抜けてしまうからですね(分割前はopenapiというプロパティーの有無で判別できます)。

そして大事なことを3つ。

  • VSCodeでJSON/YAMLファイルの補完にはJSON Schemaが使われる
  • OpenAPIのJSON Schemaはここで定義されている
  • VSCodeのワークスペースファイル(*.code-workspace)では、「どのJSON Schemaを」「どのJSON/YAMLファイルに」適用するかを指定できる

つまり、分割したファイルのJSON Schemaを用意して、ワークスペースファイルに分割したファイルとJSON Schemaの対応付けを教えてあげれば補完できそうです。

ここではcomponentsセクション以下のparametersを分割することを考えてみます。やり方がわかれば他も同じように分割できます。

やってみる

ディレクトリー構造は以下のようにしてみます。

root
- apidocs
  - components
    - parameters.yaml # 分割先ファイル(components/parameters を分割したもの)
  - doc.yaml # 分割元ファイル
- apidoc-modularize.code-workspace # ワークスペースファイル

componentsセクション以下のparametersを分割することを考えましょう。やり方がわかれば他も同じように分割できます。

parametersのJSON Schema定義はここ、つまり#/$defs/components/properties/parametersです。VSCodeがparameters.yamlを開いたときにこのJSON Schemaを参照するように教えてやればよさそうです。

apidocs.code-workspaceyaml.schemasプロパティーを追加します。このファイルはJSON形式なので、簡単にテキストエディターで編集できます。

{
  ...
  "yaml.schemas": {
    "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.json#/$defs/components/properties/parameters": [
        "./apidocs/components/parameters.yaml"
    ]
  }
}

これでparameters.yamlを開くときにschema.json#/$defs/components/properties/parametersを参照するので、無事コード補完もできてめでたしめでたし・・・とはいきませんでした。確かに該当のschema.jsonは参照してくれるのですが、ハッシュタグの先までは見てくれないようです。

ハッシュタグ部分を別ファイルにしてみる

ハッシュタグ込みのURLを認識してくれないなら、ハッシュタグ部分を別ファイルにして、そのファイルを参照させてみましょう。

このようなディレクトリ構成にします。

root
- apidocs
  - components
    - parameters.yaml # 分割先ファイル(components/parameters を分割したもの)
- json-schemas # この下にJSON Schemaファイルを入れる
  - components
    - parameters.json
  - doc.yaml # 分割元ファイル
- apidoc-modularize.code-workspace # ワークスペースファイル

そして以下のような中身のparameters.jsonを作ります。単にこの部分をJSONファイルに切り出しただけです。

{
  "type": "object",
  "additionalProperties": {
    "$ref": "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.json#/$defs/parameter-or-reference"
  }
}

最後に、あらためてapidocs.code-workspaceを以下のように編集します。

{
  ...
  "yaml.schemas": {
    "./json-schemas/components/parameters.json": [
        "./apidocs/components/parameters.yaml"
    ]
  }
}

これで、今度こそ無事補完ができました。とはいえモヤっとする解決法なので、OAI公式で各コンポーネント部分を別ファイルに切り出してくれるとありがたいですね・・・

0 件のコメント:

コメントを投稿