NestJS로 AWS S3에 여러 개의 이미지를 업로드하는 기능을 구현해보자.
AWS S3 버킷을 만들어 준다. 버킷 만드는 방법을 설명해놓은 곳이 많으니 직접 찾아서 만들면 된다.
개인적으로는 이 블로그를 참고했다.
AWS S3를 NestJS에서 적용하는 코드를 찾아보니 다양한 방식들이 나왔다. S3를 처음 사용해보는 것이라 처음에는 혼란스러웠는데, 다양한 코드를 참고해 짜집기하며 구현해보았다.
나는 NestJS의 Multer 라이브러리와 Multer-S3, 그리고 NestJS의 FilesInterceptor()
데코레이터를 사용할 것이다.
aws-sdk, multer, multer-s3를 설치한다.
npm install --save aws-sdk multer multer-s3
typescript를 사용하니 @types/multer까지 설치한다.
npm install --save-dev @types/multer
우선 NestJS 프로젝트에 image라는 이름으로 이미지 업로드하는 모듈을 만들어 코드를 작성할 예정이다.
image라는 module, controller, service를 차례로 만들어 준다.
nest g mo image
nest g co image --no-spec
nest g s image --no-spec
--no-spec
옵션을 사용하면 테스트 파일인 spec 파일 없이 만든다.
루트 디렉토리에 .env 파일을 만들어서 액세스키와 같은 중요한 정보를 따로 보관한다.
// .env
AWS_S3_BUCKET_NAME=YourBucketName
AWS_ACCESS_KEY_ID=YoutAccessKeyId
AWS_SECRET_ACCESS_KEY=YourSecretAccessKey
AWS_REGION=YourRegion
process.env.변수명
으로 불러와 사용할 수 있다.
.env 환경설정 파일을 로드하기 위한 dotenv모듈을 설치한다.
npm install --save dotenv
npm install --save -dev @types/dotenv
controller에 아래와 같이 작성한다.
// image.controller.ts
import { Controller, Post, UploadedFiles, UseInterceptors } from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';
import { ImageService } from './image.service';
import * as multerS3 from 'multer-s3';
import * as AWS from 'aws-sdk';
import 'dotenv/config';
const s3 = new AWS.S3()
@Controller('image')
export class ImageController {
constructor (
private readonly imageService: ImageService
) {}
@Post()
@UseInterceptors(FilesInterceptor('images', 3, {
storage: multerS3({
s3: s3,
bucket: process.env.AWS_S3_BUCKET_NAME,
acl: 'public-read',
key: function(req, file, cb) {
cb(null, file.originalname)
}
})
}))
async uploadImage(@UploadedFiles() files: Express.Multer.File) {
return this.imageService.uploadImage(files);
}
}
그리고 service에 아래와 같이 작성한다.
// image.service.ts
import { Injectable } from '@nestjs/common';
import * as AWS from 'aws-sdk';
AWS.config.update({
"accessKeyId": process.env.AWS_ACCESS_KEY_ID,
"secretAccessKey": process.env.AWS_SECRET_ACCESS_KEY,
"region": process.env.AWS_REGION
})
const s3 = new AWS.S3();
@Injectable()
export class ImageService {
async uploadImage(files) {
return "SUCESS";
}
}
NestJS 공식문서에 따르면 FileInterceptor()
등 파일 업로드에 사용할 수 있는 다른 데코레이터가 있다. 나는 여러 개의 파일을 업로드 할 수 있는 FilesInterceptor()
를 사용했다. 각자의 필요에 맞게 적용하면 될 것 같다.
참고사이트
https://docs.nestjs.com/techniques/file-upload
https://medium.com/@shamnad.p.s/image-upload-to-aws-s3-using-nestjs-and-typescript-b32c079963e1
http://www.nestjstutorials.com/nestjs-file-uploading-using-multer/
http://blog.naver.com/pjt3591oo/221852920854
https://studyingych.tistory.com/43
https://johnmarc.tistory.com/48
좋은 참고글 되었습니다. 감사합니다!!!