设计动机

Swagger 装饰器就是文档。它们和路由、校验或业务规则没有任何关系,却还是混进了同一个文件里。

问题

Swagger 装饰器就是文档。它们和路由、校验或业务规则没有任何关系,但最终还是混进了同一个文件里,让控制器的体积翻倍,把真正重要的代码埋在下面。

前后对比

users.controller.ts 里到处散落着 Swagger 装饰器:

users.controller.ts
// users.controller.ts
@ApiTags("users")
@Controller("users")
export class UsersController {
  @Get()
  @ApiOperation({ summary: "List all users" })
  @ApiResponse({ status: 200, description: "OK", type: [UserEntity] })
  findAll(): Promise<UserEntity[]> {
    return this.usersService.findAll();
  }

  @Post()
  @ApiOperation({ summary: "Create a user" })
  @ApiBody({ type: CreateUserDto })
  @ApiResponse({ status: 201, description: "Created", type: UserEntity })
  @ApiResponse({ status: 400, description: "Bad Request" })
  create(@Body() dto: CreateUserDto): Promise<UserEntity> {
    return this.usersService.create(dto);
  }
}

约定

nestjs-docfy 划出了一条清晰的边界:控制器表达行为,docs 文件表达文档。这个约定(*.controller.docs.ts)呼应了 NestJS 已经在用的组织方式(*.controller.spec.ts),所以从第一天起就很自然。