Fastifyで既存のOpen APIファイルを読み込んでSwagger UIで表示できるようにする

Fastifyを使った開発を始めたのですが、その際普段使っているようなOpen APIファイルを読み込むにはどうしたらいいかを調べていました。
「実装を元にOpen APIファイルを生成する+Swagger UIで見れるようにする」というものは結構出てきたのですが、逆に「既存のOpen APIファイルを読み込んでSwagger UIで見れるようにする」というものがなかなか出てこず、自分としてはこちらのニーズの方があったのでやってみました。

前提

環境としては以下でやりました。

  • Node.js v18.17.1
  • fastify v4.0.0
  • @fastify/cors v8.3.0
  • @fastify/swagger v8.8.0
  • @fastify/swagger-ui 1.9.3

Fastify のプロジェクトは作成済み。

プロジェクトはざっくりこんな感じです。

src
├── app.ts
├── plugins
├── routes
└── swagger
    └── openapi.yaml

やったこと

swagger 関連のパッケージをインストールする

$ npm i @fastify/swagger @fastify/swagger-ui

それぞれ、ざっくり以下のようなパッケージのようです。

  • @fastify/swagger: 既存実装からSwaggerファイルを生成する
  • @fastify/swagger-ui: Swagger UIの構築

組み合わせる

順を追って調整します。

まずは app.ts で以下のようにそれぞれ register しておきます。

import fastifySwagger from '@fastify/swagger';
import fastifySwaggerUi from '@fastify/swagger-ui';

const app: FastifyPluginAsync<AppOptions> = async (
  fastify,
  opts
): Promise<void> => {
  // 中略

  fastify.register(fastifySwagger);
  fastify.register(fastifySwaggerUi);

  // 略
};

これは、実装からOpen APIのデータが作られSwagger UIで見れる状態となります。

既存のSwaggerファイルを読み込めるようにする

上記実装の fastifySwagger の部分を調整します。

await fastify.register(fastifySwagger, {
    mode: 'static',
    specification: {
      baseDir: '.',
      path: join(__dirname, 'swagger/openapi.yaml'),
    },
  });

このように mode と specification の設定を入れることで既存ファイルを読み込むようになりました。

fastifySwaggerUI側だと思っていたので思わぬ盲点でした。

例えば、この状態で http://localhost:3000/documentation とかにアクセスすると既存のファイルで定義した内容を確認できます。

実際は開発環境だけ見れるようにしたいので、 NODE_ENV の値によって register する/しないの切り替えをすることになるかと思います。

おわりに

今回は主に既存ファイルをSwagger UIで確認できる状況を作りました。
生成する方もYAMLやJSONなど形式を指定してのファイル出力までできそうなので、もう少し見てみようと思いました。
こういう辺りも結構開発されているイメージなのでありがたいですね。

余談

Expressのときは swagger-express-validator を使ってレスポンスのバリデーションをかけながら実装するようなこともできましたが、その辺りは見当たりませんでした。
そこまでできるとより良さそうです。