[NestJS] Multer을 이용하여 사진 여러 장 업로드하기

Kylie·2022년 11월 3일
0
post-thumbnail
post-custom-banner

들어가기 전

이번 포스팅에서는 NestJs에서 multer을 사용하여 이미지 업로드를 해보고자 한다.

1. 프로젝트 생성

$ npm i -g @nestjs/cli
$ nest new file-upload

2. 관련 폴더 및 파일

폴더 및 파일 생성

$ nest g controller file
$ nest g service file
$ nest g module file

Multer options 설정하기


패키지 설치

$ npm i -D @types/multer

src/lib/multerOptions.ts


// 업로드 가능한 확장자 설정
export const imageFileFilter = (req, file, callback) => {
  if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) {
    return callback(new Error("Only image files are allowed!"), false);
  }
  callback(null, true);
};

// 파일명 중복을 피하기 위해 파일명 수정
export const editFileName = (req, file, callback) => {
  const name = file.originalname.split(".")[0];
  const fileExtName = file.originalname.slice(((file.originalname.lastIndexOf(".") - 1) + 2));
  const time = Date.now();
  const randomName = `${name}-${time}`
  callback(null, `${randomName}.${fileExtName}`);
};

💡 파일 업로드할 때 필요한 설정이다.
참고로 파일명을 재설정 하는 작업에서 Timestemp로 random 값을 만들었는데 다양한 방법으로 설정해도 상관없다.


File Upload 하기 (이미지 여러장)

src/file/file.moudle.ts

import { Module } from "@nestjs/common";
import { MulterModule } from "@nestjs/platform-express";
import { FileController } from "./file.controller";
import { FileService } from "./file.service";

@Module({
  imports: [
    MulterModule.register({
      dest: "./upload"
    })
  ],
  controllers: [FileController],
  providers: [FileService]
})
export class FileModule {
}

💡 MulterModule.register() improt 하고 업로드할 경로 설정하기


src/file.controller.ts

import {
  Controller, Get, Param,
  Post, Res,
  UploadedFiles,
  UseInterceptors
} from "@nestjs/common";
import { FileService } from "./file.service";
import { FilesInterceptor } from "@nestjs/platform-express";
import { diskStorage } from "multer";
import { editFileName, imageFileFilter } from "../lib/multerOptions";


// @ts-ignore
@Controller("file")
export class FileController {
  constructor(private readonly fileService: FileService) {
  }
  
  @Post("/")
  // @ts-ignore
  @UseInterceptors(FilesInterceptor("files", 5, {
    storage: diskStorage({
      destination: './upload',
      filename: editFileName
    }),
    fileFilter: imageFileFilter
  }))
  uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
    return this.fileService.uploadFiles(files);
  }

}

💡 files 필드명으로 5개까지 업로드 할 수 있도록 설정했다.
filenamefileFilter 은 방금 만든 src/lib/multerOptions.ts 에서 import 했다.


src/file/file.service.ts

import { Injectable } from "@nestjs/common";


@Injectable()
export class FileService {
  public uploadFiles(files: Array<Express.Multer.File>) {
    const result = [];

    files.forEach((file) => {
      const res = {
        originalname: file.originalname,
        filename: file.filename
      };
      result.push(res);
    });

    return result;
  }
}

src/main.ts

import { NestFactory } from "@nestjs/core";
import { NestExpressApplication } from "@nestjs/platform-express";
import { join } from "path";
import { AppModule } from "./app.module";


async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule
  );

  app.useStaticAssets(join(__dirname, "..", "upload"));
  await app.listen(9001).then(() => {
    console.log(`http://localhost:9001`);
  });
}

bootstrap();

💡 정적 파일 경로 설정해주기


3. Postman


파일 업로드 하기


upload 폴더 확인


파일 찾기

src/file/file.controller.ts

// 기존 코드에 추가하기
  @Get("/:imgpath")
  seeUploadedFile(@Param("imgpath") image, @Res() res) {
    return res.sendFile(image, { root: "./upload" });
  }



전체 코드 보기

profile
올해보단 낫겠지....
post-custom-banner

0개의 댓글