피곤핑
코딩일탈
피곤핑
전체 방문자
오늘
어제
  • 분류 전체보기
    • Kotlin & Java
    • Spring
      • Spring Security
      • Spring
    • 네트워크
    • JavaScript & Node js
    • Docker
    • Python3
    • Unity
    • 딥러닝
    • 객체지향프로그래밍
    • Error 보고서
    • 나의 이야기 & 회고
    • HTML & CSS
    • Archive
    • 독서

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • 개발자취업
  • JavaScript
  • 항해99
  • nodejs
  • 99클럽
  • 티스토리챌린지
  • Client
  • TiL
  • 오블완
  • 코딩테스트준비

최근 댓글

hELLO · Designed By 정상우.
피곤핑

코딩일탈

[nest.js] AWS s3 bucket 에 파일 여러개 업로드 + rest api 만들기
JavaScript & Node js

[nest.js] AWS s3 bucket 에 파일 여러개 업로드 + rest api 만들기

2021. 10. 26. 11:34

👉 postman 에서 실행해본 결과

파일 업로드 api 의 payload (form-data)
업로드된 파일의 Response

 

위 사진과 같이 form-data 로 여러 파일을 첨부하고 AWS s3 bucket 에 업로드 한 후 값들을 db 에 저장하고 저장된 데이터들을 response 로 리턴해주는 기능을 만들어볼 것입니다 🏄‍♀️

 

🐱 현재 이 프로젝트는 nestjs 프레임워크를 사용하고 있습니다. 

 

1.  패키지 설치 (aws-sdk, multer, multer-s3)

npm install aws-sdk multer multer-s3 --save

https://www.npmjs.com/package/multer-s3

 

multer-s3

Streaming multer storage engine for AWS S3

www.npmjs.com

이 포스트에서는 s3 bucket 업로드를 하고 있으므로 multer-s3 패키지 까지 같이 설치해 줍니다.

네스트 공식문서에도 파일업로드 하는 예제가 있지만 그 예제에는 s3 업로드 까지는 다루고 있지 않으므로 따로 설치해주셔야 합니다.

2. upload-file  서비스, 컨트롤러 생성 cli

이미 몇번 리소스를 생성해본 분들은 아시겠지만 nestjs 에서는 cli 로 리소스 파일을 자동 생성할 수 있습니다.

https://docs.nestjs.com/cli/usages#cli-command-reference

 

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

위 문서에서 보면 다양한 schematics 들을 cli 로 생성 할 수 있습니다.

현재 포스트에서는 service, controlle, module 을 따로 생성하겠습니다.

 

(1) module 생성

nest g mo upload-file

(2) constroller 생성

nest g co upload-file

(3) service 생성

nest g s upload-file

생성후 기본적인 구조는 공식문서를 참고해 주세요

 

저는 상기 사진과 같이 파일 구조를 짰습니다.

(dto, exception 은 추가하지 않아도 됩니다.)

 

3. upload-file 엔티티 생성하기

- upload-file/entity/upload-file.entity.ts

import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";

@Entity("upload_file")
export class UploadFile {
    @PrimaryGeneratedColumn("uuid")
    id:string;

    @Column()
    originalName: string;

    @Column()
    encoding: string;

    @Column()
    mimeType: string;

    @Column("decimal", { precision: 10, scale: 2 })
    size: number;

    @Column({ comment: "s3 업로드된 localtion url" })
    url: string;

    @CreateDateColumn() 
    createdAt: Date;

    @UpdateDateColumn() 
    updatedAt: Date; 
}

s3에 값을 업로드 할 때 받을 수 있는 meta data 들을 upload-file 테이블 필드에도 추가해주었습니다.

 

4. upload-file 리포지토리 생성하기

typeorm 은 사용자 지정 저장소 라는 기능을 제공합니다. 커스텀 리포지토리를 사용하면 기본 리포지토리 클래스를 확장하고 몇 가지 특수 메서드를 사용하여 강화할 수 있습니다. 
추가적인 내용은 typeorm 공식 홈페이지에 있습니다.

https://typeorm.io/#/custom-repository

 

TypeORM - Amazing ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server,

 

typeorm.io

 

- upload-file/upload-file.repository.ts

import { EntityRepository, Repository } from "typeorm";
import { UploadFile } from "./entity/upload-file.entity";

@EntityRepository(UploadFile)
export class UploadFileRepository extends Repository<UploadFile> {}

 

5.  aws-sdk, multer, multer-s3 설치하기

업로드에 필요한 패키지를 설치해줍니다.

 

- npm

npm install aws-sdk multer multer-s3 --save

 

공식문서에서는 multer 만을 다루고 있으나 

본 포스팅에서는 aws 의 s3 bucket 으로 파일을 업로드 할 것이기 때문에 위의 3 패키지 모두 설치해줍니다!

(s3 bucket 이 이미 생성되어있고 aws accesskey, secretkey, s3 bucket name 을 모두 안다는 가정하에 진행합니다.)

6. upload-file 컨트롤러 로직 

- upload-file.controller.ts

import {
  Controller,
  Post,
  UploadedFiles,
  UseInterceptors,
} from '@nestjs/common';
import * as AWS from 'aws-sdk';
import * as multerS3 from 'multer-s3';
import { FilesInterceptor } from '@nestjs/platform-express/multer/interceptors/files.interceptor';
import { UploadFileService } from './upload-file.service';

// AWS S3
const s3 = new AWS.S3();
AWS.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: 'ap-northeast-2'
});

@Controller('/file')
export class UploadFileController {
  constructor(private readonly UploadFileService: UploadFileService) { }

  @Post()
  @UseInterceptors(FilesInterceptor('file', 10, {
    storage: multerS3({
      s3: s3,
      bucket: process.env.AWS_S3_BUCKET_NAME,
      acl: 'public-read',
      key: function (request, file, cb) {
        cb(null, `${Date.now().toString()}-${file.originalname}`);
      },
    }),
    limits: {}
  }),
  )
  async uploadFile(
    @UploadedFiles() files: Express.MulterS3.File[],
  ) {

    return this.UploadFileService.uploadFile(files);
  }
}

 

1) aws s3 config 설정

아래와 코드와 같이 aws access key, secret key 가 필요합니다. 

저는 .env 파일의 환경변수로 설정했습니다.

import * as AWS from 'aws-sdk';
import * as multerS3 from 'multer-s3';

// AWS S3
const s3 = new AWS.S3();
AWS.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: 'ap-northeast-2'
});

 

2) @UseInterceptors 설정

https://docs.nestjs.com/techniques/file-upload#array-of-files

 

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

FileInterceptor 에 최대 10장으로 limit 을 줬으므로 10장 까지만 업로드 하능합니다.

파일 사이즈도 limit 을 주고 싶다면 아래 캡처 처럼 limit 에서 여러 파라미터로 옵션을 줄 수 있습니다.

7. upload-file 서비스 로직 

- upload-file.service.ts

import { BadRequestException, Injectable } from '@nestjs/common';
import { UploadFileRepository } from './upload-file.repository';
import { UploadFile } from './entity/upload-file.entity';

@Injectable()
export class UploadFileService {
  constructor(
    private readonly UploadFileRepository: UploadFileRepository
  ) { }

  async uploadFile(
    files: Express.MulterS3.File[],
  ) {

    const uploadfiles = [];
    for (const element of files) {
      const file = new UploadFile();
      file.originalName = element.originalname
      file.encoding = element.encoding
      file.mimeType = element.mimetype
      file.size = element.size
      file.url = element.location

      uploadfiles.push(file)
    }

    try {
      return { "data": await this.UploadFileRepository.save(uploadfiles) };
    } catch (error) {
      throw new BadRequestException(error.message)
    }
  }
}

 

8. 완성!

postman 을 사용하여 api 테스트를 해보았습니다.

nestjs 에서의 POST 는 기본으로 201 코드를 줍니다.

 

 

📝 Ref

https://docs.nestjs.com/techniques/file-upload#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

https://codesk.tistory.com/61

 

[바미] Nestjs 및 TypeScript를 사용하여 AWS S3에 이미지 업로드

Nestjs 및 TypeScript를 사용하여 AWS S3에 이미지 업로드 최근 프로젝트에서 백엔드에 있는 Nestjs와 Typescript를 사용하여 AWS S3에 이미지를 업로드해야 했습니다. Typescript와 Nestjs를 사용하여 이 작업을..

codesk.tistory.com

 

'JavaScript & Node js' 카테고리의 다른 글

[nodejs/strapi] 🚀 강력한 headless 프레임워크 strapi 사용해보기 [2/3]  (0) 2021.10.29
[nodejs/strapi] 🚀 강력한 headless 프레임워크 strapi 사용해보기 [1/3]  (0) 2021.10.28
npm ERR! must provide string spec  (0) 2021.07.13
[JavaScript] 정규표현식 (Regular Expression)  (0) 2020.07.07
[Redux] 노드 리액트 Redux 기본 구조 만들기!  (0) 2020.07.01
    'JavaScript & Node js' 카테고리의 다른 글
    • [nodejs/strapi] 🚀 강력한 headless 프레임워크 strapi 사용해보기 [2/3]
    • [nodejs/strapi] 🚀 강력한 headless 프레임워크 strapi 사용해보기 [1/3]
    • npm ERR! must provide string spec
    • [JavaScript] 정규표현식 (Regular Expression)
    피곤핑
    피곤핑

    티스토리툴바