O que é o nestjs-docfy

Uma camada de tooling para NestJS que move os decorators Swagger para fora dos controllers, sem perder tipagem nem gerar OpenAPI diferente.

O problema

Controllers NestJS documentados com @nestjs/swagger rapidamente acumulam dezenas de @ApiOperation, @ApiResponse, @ApiBody e @ApiTags, a ponto de a lógica real da rota ficar enterrada sob metadados de documentação.

A solução

O nestjs-docfy introduz uma convenção simples: para cada *.controller.ts, existe um *.controller.docs.ts ao lado, contendo toda a documentação. É o mesmo padrão que o Nest já usa para *.spec.ts.

  • Zero mudança no output do OpenAPI gerado.
  • Tipagem preservada: o companion file importa a classe do controller.
  • Discovery em require.cache, antes de SwaggerModule.createDocument().

Antes e depois

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' }),
    ],
  },
});
Limitação conhecida

A descoberta de companion files depende de require.cache e, por isso, não funciona com nest-cli.json configurado com "webpack": true. Para esses projetos, use o fluxo alternativo com nestjs-docfy patch-spec.

Quando usar

Encaixa bem quando

  • Sua API tem dezenas de endpoints e vários responses por rota.
  • Sua equipe trata OpenAPI como contrato versionado.
  • Você quer CI gates objetivos (coverage mínimo, lint de docs).
AI-first

O pacote companheiro docfy-ui renderiza a referência de API com um botão Copy for AI em cada endpoint, ideal para colar em LLMs.