😎

[Nest][openapi]multipart request /File and DTO

2023/11/14に公開

multipart request/File and DTO

fileとDTOを分割したbodyを設定したい場合のメモ
認証など省略しているので、そのままは使わない事

POINT

  • @ApiExtraModelsで使用していないDTOなどを生成できる
  • @ApiBodyでBodyを自作する
  • $ref: getSchemaPath(CreateUserDto)でswaggerのpathを参照できる
  • @Bodyから@Req()にする

controller 上部

CONTROLLER
@ApiTags('user')
@Controller('user')
@ApiExtraModels(CreateUserDto)  //←他にDTO使っていない場合必要
export class UserController {
 ~~~~~
}

controller 内部

ENDPOINT
@Post()
  @ApiConsumes('multipart/form-data')
  @ApiBody({  //←これでBODYを作る
    description: 'Create a new user',
    schema: {
      type: 'object',
      required: ['createCreatorDto', 'file'],
      properties: {
        createUserDto: { 
          $ref: getSchemaPath(CreateUserDto),  //←これでDTOを参照する
        },
        file: {
          type: 'string',
          format: 'binary',
        },
      },
    },
  })
  @UseInterceptors(FileInterceptor('file', { limits: { fileSize: 1024 * 1024 * 4 } }))
  async create(
    @Req() req: Request,  //←form-dataの場合はDTOを全て受け取る
    @UploadedFile(
      new ParseFilePipeBuilder()
        .addFileTypeValidator({ fileType: /(jpg|jpeg|png|webp|gif|3avif)$/, })
        .build(
          {
            fileIsRequired: false,
          }
        ),
    )
    file: Express.Multer.File | null,
  ): Promise<void> {
    const createUserDto: CreateUserDto = JSON.parse(req.body['createUserDto'] as string);//←DTOに変換する
    await this.userService.create(createUserDto, file);
  }

Discussion