Motivation

Les décorateurs Swagger, c'est de la documentation. Ils n'ont rien à voir avec le routage, la validation, ou les règles métier, et pourtant ils finissent mélangés dans le même fichier.

Le problème

Les décorateurs Swagger, c'est de la documentation. Ils n'ont rien à voir avec le routage, la validation, ou les règles métier, mais ils finissent mélangés dans le même fichier, doublant la taille du contrôleur et enterrant le code qui compte vraiment.

Avant et après

users.controller.ts avec des décorateurs Swagger éparpillés partout :

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);
  }
}

La convention

nestjs-docfy impose une frontière claire : les contrôleurs expriment le comportement, les fichiers docs expriment la documentation. La convention (*.controller.docs.ts) reflète la façon dont NestJS organise déjà les specs (*.controller.spec.ts), donc ça semble naturel dès le premier jour.