nestjs-docfyとは

型付けを失わず、生成されるOpenAPI出力も変えずに、Swaggerデコレーターをコントローラーから切り離すNestJSツールリング層です。

問題

@nestjs/swaggerでドキュメント化されたNestJSコントローラーは、あっという間に何十もの@ApiOperation@ApiResponse@ApiBody@ApiTagsを抱え込み、ルートの本当のロジックがドキュメントメタデータの下に埋もれてしまいます。

解決策

nestjs-docfyはシンプルな規約を導入します。すべての*.controller.tsに対して、隣に*.controller.docs.tsを置き、そこにすべてのドキュメントを保持します。Nestがすでに*.spec.tsで使っているのと同じパターンです。

  • 生成されるOpenAPI出力への変更はゼロです。
  • 型付けは保持されます。コンパニオンファイルはコントローラークラスをインポートします。
  • SwaggerModule.createDocument()より前に、require.cache経由で検出されます。

導入前後

users.controller.ts
@WithDocs()
@Controller('users')
export class UsersController {
  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.users.findOne(id);
  }
}
users.controller.docs.ts
docs(UsersController, {
  classDecorators: [ApiTags('Users')],
  methods: {
    findOne: [
      ApiParam({ name: 'id', type: String }),
      ApiOperation({ summary: 'Get user by id' }),
      ApiResponse({ status: 200, type: UserDto }),
      ApiResponse({ status: 404, description: 'User not found' }),
    ],
  },
});
webpack: true

コンパニオンファイルの検出はrequire.cacheに依存しているため、nest-cli.json"webpack": trueが設定されている場合、実行時には動作しません。そのようなプロジェクトでは、代わりにCLI pluginを登録してください。ビルドのたびに、根本から自動でこれを修正します。

いつ使うか

こんなときに向いている

  • あなたのAPIには何十ものエンドポイントがあり、ルートごとに複数のレスポンスがあります。
  • あなたのチームはOpenAPIをバージョン管理された契約として扱っています。
  • 客観的なCIゲート(最小カバレッジ、docsのlint)が欲しいと思っています。
AI-first

コンパニオンパッケージのdocfy-uiは、すべてのエンドポイントにCopy for AIボタンを備えたAPIリファレンスを描画します。LLMへの貼り付けに最適です。