NestJS에서 AWS Multer S3 를 활용하여 이미지 업로드하기

package 설치

$ pnpm add -wED @types/multer

해당 패키지를 설치하면 Express.Multer.File 유형을 사용할 수 있다.

사용법

단일 파일을 업로드하려면 FileIntercepter() 를 경고 핸들러로 연결하고 @UploadFile() 데코레이터를 사용하여 요청으로부터 파일을 추출한다.

@Post('upload')
@Useinterceptors(FileIntercepter('file', [options]))
uploadFile(@UploadFile() file: Express.Multer.File) {
	console.log(file);
}

AWS S3 multer 관련 설정

import { Controller, Post, UploadedFile, UseInterceptors } from "@nestjs/common";
import { FileInterceptor } from "@nestjs/platform-express";

@Controller('uploads')
export class UploadsController {
  @Post('')
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(@UploadedFile() file) {
    console.log(file)
  }
}

위에서 찍은 콘솔에는 fieldname, originalname, encoding, mimetype, buffer, size 이렇게 파일에 대한 정보가 나온다.

이제 위의 정보를 AWS S3에 저장하기 위해 aws-sdk 관련 패키지를 설치해주면 된다.

✔️ aws-sdk와 @aws-sdk/client-s3를 설치해주면 된다.

AWS S3 multer upload 구현

service 파일에서 다음과 같이 사진 업로드 코드를 작성할 수 있다.

아래 코드는 사용자 전체 프로필 업데이트와 함께 결합하여 구현했기 때문에 다른 코드가 섞여있다.

async update(
  updateAccountRequestDto: UpdateAccountRequestDto
): Promise<DefaultResponse> {
  const validateAccount = await this.validateAccountByUrn(
    ...
  );
  if (!validateAccount) {
    ...
  }

  const updateData = updateAccountRequestDto.updateData();

  const { profileImg } = updateAccountRequestDto;
  this.uploadFile(profileImg);

  const updateAccount = await this.db
    .collection('...')
    .updateOne({ ... }, { $set: updateData });
  return {
    statusCode: ...,
    data: JSON.stringify(updateAccount),
  };
}

async uploadFile(@UploadedFile() file) {
  AWS.config.update({
    region: [region],
    credentials: {
      accessKeyId: process.env.[Access key ID],
      secretAccessKey: process.env.[Secret Access Key ID],
    },
  });
  try {
    const upload = await new AWS.S3()
      .putObject({
        Key: `${Date.now() + file.originalname}`,
        Body: file.buffer,
        Bucket: process.env.[Bucket Name],
      })
      .promise();
    console.log(upload);
    return upload;
  } catch (err) {
    console.log(err);
  }
}

s3Config는 @aws-sdk/client-s3를 통해 S3의 region 및 access-key 설정에 관한 변수이다.

이제 위 코드를 통해 s3 bucket에 이미지를 업로드할 수 있다. (controller)

@GrpcMethod(ACCOUNT_SERVICE_NAME, 'update')
@UseInterceptors(FileInterceptor('image'))
private async update(
  @Body() payload: UpdateAccountRequestDto
): Promise<DefaultResponse> {
  return this.accountService.update(payload);
}

@UseInterceptors(FileInterceptor('image')) 를 통해 이미지 검증 과정을 거친다.