728x90

- 설치

yarn add -D @types/multer

nest는 기본적으로 Multer를 내장하고 있어 타입만


- 적용

경로 최상단에 public > movie, temp 폴더 각각 생성

// movie.module.ts

imports: [
    MulterModule.register({
      storage: diskStorage({
        destination: join(process.cwd(), 'public', 'movie'),
      }),
    }),
  ],

 

- 단수

// movie.controller.ts 
// 단수

@Post()
  @RBAC(Role.admin)
  @UseInterceptors(TransactionInterceptor)
  @UseInterceptors(FileInterceptor('movie'))
  postMovie(
    @Body() body: CreateMovieDto, //
    @QueryRunnerDeco() queryRunner: QueryRunner,
    @UserId() userId: number,
    @UploadedFile() file: Express.Multer.File,
  ) {
    console.log(file);
    return this.movieService.create(body, userId, queryRunner);
  }

 

- 복수

// movie.controller.ts 
// 복수

@Post()
  @RBAC(Role.admin)
  @UseInterceptors(TransactionInterceptor)
  @UseInterceptors(FilesInterceptor('movies'))
  postMovie(
    @Body() body: CreateMovieDto, //
    @QueryRunnerDeco() queryRunner: QueryRunner,
    @UserId() userId: number,
    @UploadedFiles() files: Express.Multer.File[],
  ) {
    console.log(files);
    return this.movieService.create(body, userId, queryRunner);
  }

 

- 여러 종류의 파일들

// movie.controller.ts 
// 여러 종류

@Post()
  @RBAC(Role.admin)
  @UseInterceptors(TransactionInterceptor)
  @UseInterceptors(
    FileFieldsInterceptor([
      {
        name: 'movie',
        maxCount: 1,
      },
      {
        name: 'poster',
        maxCount: 2,
      },
    ]),
  )
  postMovie(
    @Body() body: CreateMovieDto, //
    @QueryRunnerDeco() queryRunner: QueryRunner,
    @UserId() userId: number,
    @UploadedFiles()
    files: {
      movie?: Express.Multer.File[];
      poster?: Express.Multer.File[];
    },
  ) {
    console.log(files);
    return this.movieService.create(body, userId, queryRunner);
  }


- Multer Options

@UseInterceptors(
    FileFieldsInterceptor(
      [
        {
          name: 'movie',
          maxCount: 1,
        },
        {
          name: 'poster',
          maxCount: 2,
        },
      ],
      {
        limits: {
          fileSize: 2000000,
        },
        fileFilter(req, file, callback) {
          console.log(file);
          if (file.mimetype !== 'video/mp4')
            return callback(
              new BadRequestException('MP4 파일만 업로드 가능합니다!'),
              false,
            );
          return callback(null, true);
        },
      },
    ),
  )

위의 3가지 인터셉터에 다 적용 가능, 위코드는 파일 크기와 형식체크예시이고, 외에도 여러가지 옵션들 있음.


- 업로드된 파일 정보 변경

yarn add uuid
// movie.module.ts

import { v4 } from 'uuid';

imports: [
    MulterModule.register({
      storage: diskStorage({
        destination: join(process.cwd(), 'public', 'movie'),
        filename: (req, file, cb) => {
          const split = file.originalname.split('.');
          let extention = 'mp4';
          if (split.length > 1) {
            extention = split[split.length - 1];
          }
          cb(null, `${v4()}+${Date.now()}.${extention}`);
        },
      }),
    }),
  ],

uuid + 날짜 + 원래 파일의 형식으로 파일 이름 변경

 

+ pipe 방법도 있지만 비효율적인듯. 필요하면 강의 보기.

 

+ DB 저장은 entity에 path column 만들고, path + filename 넣는식으로 넣으면됨

        movieFilePath: join(movieFolder, movieFileName),

- 파일 서빙

yarn add @nestjs/serve-static
// app.module.ts

imports: [
    ServeStaticModule.forRoot({
      rootPath: join(process.cwd(), 'public'),
      serveRoot: '/public/',
    }),
  ],

rootPath를 세부적으로 작성하지 않으면 모든 파일을 불러올 수 있음. => 업로드 파일 저장되는 폴더 주소로 path 고정/제한

movie 폴더일 경우 요청 주소가 "주소/movie/파일이름" 같은 형식이 될텐데 이러면 movie의 get path와 겹치게 됨.

이를 방지하기 위해 serveRoot를 지정하고 요청 주소를 "주소/public/movie/파일이름" 으로 변경함.


- 선 업로드

    await rename(
      join(process.cwd(), tempFoler, createMovieDto.movieFileName),
      join(process.cwd(), movieFolder, createMovieDto.movieFileName),
    );

temp 저장하고, 파일 이름 front로 보낸 후, front에서 등록할 때 받았던 이름 같이 보내주면 그거 저장 후 위 코드로 파일 위치 변경


https://fastcampus.co.kr/classroom/239666

 

728x90

'코딩 > Nest.js' 카테고리의 다른 글

Task Scheduling  (1) 2024.10.26
Caching  (2) 2024.10.25
Custom Decorator  (1) 2024.10.24
Exception Filter  (1) 2024.10.23
Interceptor  (1) 2024.10.23

+ Recent posts