在nestjs下可以用類似ASP.net core或是Java中類似的reflection機制方式,利用Decorators及Swagger Module自動產生API文件頁面。
yarn add @nestjs/swagger
在main.ts下,加入產生Swagger頁面的程式碼
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
    
  // 建立Swagger頁面設定檔  
  const userApiOptions = new DocumentBuilder()
            .setTitle('User API Doc')
            .setDescription('User API Info')
            .setVersion('1.0')
            .addBearerAuth()
            .addTag('users') // match tags in controllers
            .build();
  
  // 沒有指定第三個參數代表所有Module的controller都會被偵測
  const userApiDocument= SwaggerModule.createDocument(app, userApiOptions);
  // 指定Swagger API頁面路徑及傳入nest app及頁面設定檔
  SwaggerModule.setup('v1/api/', app, userApiDocument);
  await app.listen(3000);
  
}
bootstrap();
啟動nestjs
可以看到Parameter底下UserDTO沒有相關資訊
傳遞物件參數包含@Body、@Query所參考到的物件,如UserDTO、userQueryDTO,要在Swagger頁面顯示物件資訊,透過@ApiModelProperty
userDTO.ts
export class UserDTO {
    @ApiModelProperty({
        maxLength:10,
        description:'Username'
    })
    ...
    username: string;
    @ApiModelProperty({
        uniqueItems: true,
        description:'Email',
        maxLength: 100
    })
    ...
    email: string;
    
    @ApiModelProperty()
    ...
    depId: number;
    @ApiModelProperty({required: false})
    ...
    roleIds: number[];
}

userQueryDTO
export class UserQueryDTO{
    
    @ApiModelProperty({
        description:'username keyword',
    })
    @IsString()
    name: string;
    
    @ApiModelProperty({
        description:'Page No',
        default:1,
    })
    @IsNumber({})
    page: number;
    @ApiModelProperty({
        description:'Records Per Page',
        default:5,
    })
    @IsNumber()
    pageSize: number;
}

不同Http回應的code顯示訊息,透過@ApiOkResponse、@ApiCreatedResponse等來套用在controller下對應的方法,詳細@ApixxResponse清單上官網查詢
以user.controller為例
@ApiUseTags('users')
@ApiBearerAuth()
@ApiForbiddenResponse({description:'Unauthorized'})
@UseGuards(AuthGuard())
@Controller('users')
export class UsersController {
    constructor(
        private usersService: UsersService,
    ){}
  @ApiOkResponse({description:'Return Users Array'})
  @Get()
  userList(@Query() query: UserQueryDTO){
    return this.usersService.getUsers(query);
  }
  ...
  @Post()
  // 回傳201的療術
  @ApiCreatedResponse({description:'User Created'})
  // 回傳Internal Error的描述
  @ApiInternalServerErrorResponse({description:'Invalid Input'})
  @UsePipes(UserDTOValidationPipe)
  @ReflectMetadata('roles', ['admin', 'superuser'])
  create(@Body() userDTO: UserDTO){
    //throw new HttpException('糟糕!您的要求有問題,請洽系統管理員', HttpStatus.BAD_REQUEST);
    return this.usersService.addUser(userDTO);
    //return this.userRepo.createAndSave(userDTO); not work
  }
可以根據Exeception Filter顯示的message來設定Error類的Response的描述
Swagger Module是依據Module來區分頁面,現在的專案下,只有UserModule跟AuthModule,可以用不同路徑來區分
main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const userApiOptions = new DocumentBuilder()
            .setTitle('User API Doc')
            .setDescription('User API Info')
            .setVersion('1.0')
            .addBearerAuth()
            .addTag('users') // match tags in controllers
            .build();
  const userApiDocument= SwaggerModule.createDocument(app, userApiOptions, {include: [UserModule]});
  SwaggerModule.setup('v1/api/user', app, userApiDocument);
  const authApiOptions = new DocumentBuilder()
            .setTitle('Auth API Doc')
            .setDescription('Auth API Info')
            .setVersion('1.0')
            .addBearerAuth()
            .addTag('auth') // match tags in controllers
            .build();
  const authApiDocument= SwaggerModule.createDocument(app, authApiOptions, {include: [AuthModule]});
  SwaggerModule.setup('v1/api/auth', app, authApiDocument);
  await app.listen(3000);
  
}
bootstrap();

Auth API獨立另外一個頁面