👉 postman 에서 실행해본 결과


위 사진과 같이 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
[바미] 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 |