ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AWS S3, Nest.js] Nest.js에서 file S3에 저장하기
    Back-end 2022. 1. 24. 21:07

     

    안녕하세요! 오늘은 Nest.js에서 AWS S3에 파일을 업로드 하는 법을 포스팅하려 합니다!

    우선 Nest.js에서 파일을 핸들하기 위한 controller가 필요합니다. 우선 nest명령어를 통해 uploads라는 모듈을 만들어봅니다.

    nest g mo uploads

     

    그리고 모듈이 만들어지면 uploads.controller.ts라는 컨트롤러를 생성해줍니다.

    https://docs.nestjs.com/techniques/file-upload

     

    Documentation | NestJS - A progressive Node.js framework

    Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac

    docs.nestjs.com

    그리고 공식문서에서 basic example을 살펴봅시다.

    nest js 공식문서

     

    예시에 따라 관련된 컨트롤러 코드를 작성합니다.

    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)
        }
    }

    uploads.controller.ts에 작성한 코드입니다. Controller url을 uploads로 정하고, file의 키값을 가지는 파일을 제공받을 예정입니다!

    그리고, 적당한 postman 같은 전송 api를 활용해 자신이 받은 파일을 확인해봅니다.

     

    insomnia

    다음과 같이 'file'이라는 이름의 키 값을 설정했기 때문에, 이미지 파일을 전송해보았습니다.

    그리고, 콘솔에서 받은 이미지파일 정보를 확인합니다.

    다음과 같은 정보의 파일을 받은 것을 확인할 수 있습니다.

    이제 이 파일을 AWS S3에 저장해야합니다! 그러기 위해선 aws-sdk라는 패키지를 설치해주어야합니다.

     

    npm install aws-sdk

    이제 AWS에서 S3에 엑세스가 가능한 IAM계정을 하나 만듭니다.

    저는 다음과 같은 사용자를 만들었습니다.

     

    import { Controller, Post, UploadedFile, UseInterceptors } from "@nestjs/common";
    import { FileInterceptor } from "@nestjs/platform-express";
    import * as AWS from 'aws-sdk'
    
    
    
    @Controller('uploads')
    export class UploadsController {
        @Post('')
        @UseInterceptors(FileInterceptor('file'))
        uploadFile(@UploadedFile() file) {
            AWS.config.update({
                credentials: {
                    accessKeyId: process.env.AWS_ACCESS_KEY,
                    secretAccessKey: process.env.AWS_SECRET_KEY,
                }
            })
            console.log(file)
        }
    }

    유저를 생성한 뒤, 받은 엑세스 키와 시크릿 키를 환경변수에 저장해 제공합니다.

    이제 우리가 파일을 저장할 버킷이 필요합니다! 버킷을 만들어봅니다.

     

    import {
      Controller,
      Post,
      UploadedFile,
      UseInterceptors,
    } from '@nestjs/common';
    import { FileInterceptor } from '@nestjs/platform-express';
    import * as AWS from 'aws-sdk';
    
    @Controller('uploads')
    export class UploadsController {
      @Post('')
      @UseInterceptors(FileInterceptor('file'))
      async uploadFile(@UploadedFile() file) {
        AWS.config.update({
          credentials: {
            accessKeyId: process.env.AWS_ACCESS_KEY,
            secretAccessKey: process.env.AWS_SECRET_KEY,
          },
        });
        try {
          const upload = await new AWS.S3()
            .createBucket({ Bucket: '버킷이름' })
            .promise();
          console.log(file);
          console.log(upload);
        } catch (error) {}
      }
    }

    참고로, 버킷 이름은 굉장히 유니크한 이름으로 하여야합니다! AWS전체에서 유일한 이름이여야 합니다!

     

    버킷을 만들었으면, 이제 putObject 메소드를 이용해 버킷에 첫 번째 파일을 올려봅시다!

    import {
      Controller,
      Post,
      UploadedFile,
      UseInterceptors,
    } from '@nestjs/common';
    import { FileInterceptor } from '@nestjs/platform-express';
    import * as AWS from 'aws-sdk';
    
    const BUCKET_NAME = '버킷 이름';
    
    @Controller('uploads')
    export class UploadsController {
      @Post('')
      @UseInterceptors(FileInterceptor('file'))
      async uploadFile(@UploadedFile() file) {
        AWS.config.update({
          region: 'ap-northeast-2',
          credentials: {
            accessKeyId: process.env.AWS_ACCESS_KEY,
            secretAccessKey: process.env.AWS_SECRET_KEY,
          },
        });
        try {
          const upload = await new AWS.S3()
            .putObject({
              Key: `${Date.now() + file.originalname}`,
              Body: file.buffer,
              Bucket: BUCKET_NAME,
            })
            .promise();
          console.log(upload);
        } catch (error) {
          console.log(error);
        }
      }
    }

    키는 유니크해야 하기 때문에 Date.now()를 넣어주었습니다. 이렇게 하고 다시 파일을 푸시하면, 우리는 버킷에 이미지가 저장되 있는 것을 확인할 수 있을 것입니다.

     

    이미지가 저장 되어있으면, 우리는 이 url을 리턴하여, 데이터베이스에 저장해야 할 것입니다. 이미지가 저장된 aws url을 확인한 뒤 그 스트링값을 데이터베이스에 저장하도록 합시다! 그러면, 프론트엔드에서 해당 url을 받아 작업을 할 수 있을 것입니다.

    감사합니다!

    댓글

sangjun's blog