From 2f83a813bb78b88da8b348cf0c4d75794caea3f2 Mon Sep 17 00:00:00 2001 From: kmi0817 Date: Thu, 16 Nov 2023 18:45:53 +0900 Subject: [PATCH] =?UTF-8?q?add:=20Nest=EC=99=80=20ObjectStorage=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yaongmeow --- BE/src/app.controller.ts | 21 ++++++++++++++++-- BE/src/app.module.ts | 2 ++ BE/src/storage/storage.module.ts | 8 +++++++ BE/src/storage/storage.service.ts | 37 +++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 BE/src/storage/storage.module.ts create mode 100644 BE/src/storage/storage.service.ts diff --git a/BE/src/app.controller.ts b/BE/src/app.controller.ts index cce879e..3ffacc8 100644 --- a/BE/src/app.controller.ts +++ b/BE/src/app.controller.ts @@ -1,12 +1,29 @@ -import { Controller, Get } from '@nestjs/common'; +import { + Controller, + Get, + Post, + UploadedFile, + UseInterceptors, +} from '@nestjs/common'; import { AppService } from './app.service'; +import { StorageService } from './storage/storage.service'; +import { FileInterceptor } from '@nestjs/platform-express'; @Controller() export class AppController { - constructor(private readonly appService: AppService) {} + constructor( + private readonly appService: AppService, + private readonly storageService: StorageService + ) {} @Get() getHello(): string { return this.appService.getHello(); } + + @Post('/upload') + @UseInterceptors(FileInterceptor('file')) + async upload(@UploadedFile() file: Express.Multer.File) { + return this.storageService.upload(file); + } } diff --git a/BE/src/app.module.ts b/BE/src/app.module.ts index be72e73..96967fc 100644 --- a/BE/src/app.module.ts +++ b/BE/src/app.module.ts @@ -7,6 +7,7 @@ import { TimelinesModule } from './timelines/timelines.module'; import { AuthModule } from './auth/auth.module'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { DatabaseModule } from './database/database.module'; +import { StorageModule } from './storage/storage.module'; @Module({ imports: [ @@ -14,6 +15,7 @@ import { DatabaseModule } from './database/database.module'; envFilePath: `.env`, isGlobal: true, }), + StorageModule, UsersModule, PostingsModule, TimelinesModule, diff --git a/BE/src/storage/storage.module.ts b/BE/src/storage/storage.module.ts new file mode 100644 index 0000000..9183e1b --- /dev/null +++ b/BE/src/storage/storage.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { StorageService } from './storage.service'; + +@Module({ + providers: [StorageService], + exports: [StorageService], +}) +export class StorageModule {} diff --git a/BE/src/storage/storage.service.ts b/BE/src/storage/storage.service.ts new file mode 100644 index 0000000..39684e9 --- /dev/null +++ b/BE/src/storage/storage.service.ts @@ -0,0 +1,37 @@ +import { Injectable } from '@nestjs/common'; +import { v4 as uuidv4 } from 'uuid'; +import * as AWS from 'aws-sdk'; + +@Injectable() +export class StorageService { + private readonly s3: AWS.S3 = new AWS.S3({ + endpoint: 'https://kr.object.ncloudstorage.com', + region: process.env.AWS_REGION, + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + }, + }); + private readonly bucketName = 'traveline'; + + private generateFilename(originalname: string) { + const extension = originalname.split('.').pop(); + const uniqueId = uuidv4(); + return `${uniqueId}.${extension}`; + } + + async upload(file: Express.Multer.File) { + const uploadParams = { + Bucket: this.bucketName, + Key: this.generateFilename(file.originalname), + Body: file.buffer, + ACL: 'public-read', + }; + + const result = await this.s3.upload(uploadParams).promise(); + + return { + imageUrl: result.Location, + }; + } +}