Cos'è nestjs-docfy

Un livello di tooling per NestJS che sposta i decorator Swagger fuori dai controller, senza perdere la tipizzazione né generare un output OpenAPI diverso.

Il problema

I controller NestJS documentati con @nestjs/swagger accumulano rapidamente decine di @ApiOperation, @ApiResponse, @ApiBody e @ApiTags, al punto che la vera logica della rotta finisce sepolta sotto i metadati di documentazione.

La soluzione

nestjs-docfy introduce una convenzione semplice: per ogni *.controller.ts esiste un *.controller.docs.ts accanto, che contiene tutta la documentazione. È lo stesso pattern che Nest usa già per *.spec.ts.

  • Zero cambiamenti all'output OpenAPI generato.
  • Tipizzazione preservata: il file companion importa la classe controller.
  • Discovery tramite require.cache, prima di SwaggerModule.createDocument().

Prima e dopo

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

La discovery del file companion dipende da require.cache, quindi non funziona a runtime con nest-cli.json configurato con "webpack": true. Per quei progetti, registra invece il plugin CLI, dato che risolve questo automaticamente, alla radice, a ogni build.

Quando usarlo

È adatto quando

  • La tua API ha decine di endpoint e più risposte per rotta.
  • Il tuo team tratta OpenAPI come un contratto versionato.
  • Vuoi gate CI oggettivi (copertura minima, linting della documentazione).
AI-first

Il pacchetto companion docfy-ui renderizza il riferimento API con un pulsante Copy for AI su ogni endpoint, ideale da incollare negli LLM.