NestJS Server에 저장된 파일을 AWS S3버킷에 업로드 하기 - 2 : 클라이언트에서 받은 파일을 올리기

이번에는 클라이언트에서 받은 파일을 NestJS을 이용하여 S3버킷에 올리도록 하겠습니다.


이전글 : NestJS Server에 저장된 파일을 AWS S3버킷에 업로드 하기 - 1 : 서버의 파일을 올리기


// /src/aws/aws.service.ts
import { HttpException, Injectable } from '@nestjs/common';
import * as AWS from 'aws-sdk';
import * as fs from 'fs';
import * as path from 'path';

// 현재 실행되고 있는 root경로를 확인하고 pa에 저장
const pa = path.dirname(__dirname).replace('/dist', '');

@Injectable()
export class AwsService {
// S3버킷을 .env파일에서 입력한다.
private AWS_S3_BUCKET = process.env.S3_BUCKET;
// s3를 사용하기 위해서 IAM계정의 ACCESS, SECRET_ACCESS KEY를 입력한다.
private s3 = new AWS.S3({
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
});

convertBinary(fileName: string) {
return fs.readFileSync(pa + '/uploads/' + fileName);
}

// AWS 버킷에 파일 upload
async uploadFile(file) {
// savename은 실제 S3 버킷에 저장될시 파일 이름을 말합니다
const { savename } = file;
console.log('savename : ', savename);
return await this.s3_upload(
file.buffer, // 파일 버퍼(binary file)
this.AWS_S3_BUCKET, // 저장할 S3버킷 이름
savename, // S3버킷에 저장할 파일 이름
file.mimetype, // 파일타입 : 위 코드에서는 'application/octet-stream'을 사용합니다.
);
}

// 실제 AWS에 파일을 업로드 하는 method
async s3_upload(file, bucket, name, mimetype) {
const params = {
Bucket: bucket,
Key: String(name),
Body: file,
ACL: 'public-read',
ContentType: mimetype,
ContentDisposition: 'inline',
CreateBucketConfiguration: {
LocationConstraint: process.env.s3_REGION,
},
};

console.log(params);

try {
let s3Response = await this.s3.upload(params).promise();

console.log(s3Response);
return s3Response;
} catch (err) {
console.log(err);
throw new HttpException(err.message, err.status ? err.status : 500);
}
}

// 서버에서 uploads폴더에 존재하는 파일을 삭제해 줍니다.
remove(fileName: string) {
fs.rm(pa + '/uploads/' + fileName, { recursive: true }, (err) => {
if (err) throw err;
console.log(`file deleted.....`);
console.log(`name : ${fileName}`);
});

return {
result: true,
message: `"${fileName}"은 삭제되었습니다.`,
};
}
}

코드1) 서비스 부분 코딩


// /src/aws/aws.controller.ts
import {
Controller,
Post,
Query,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger';
import { AwsService } from './aws.service';

@ApiTags('AWS S3 버킷으로 파일을 올리기')
@Controller('aws')
export class AwsController {
constructor(private readonly awsService: AwsService) {}

@Post('aws/upload/client/file')
@ApiOperation({ summary: '파일을 서버쪽으로 upload' })
@ApiConsumes('multipart/form-data')
@ApiBody({
schema: {
type: 'object',
properties: {
file: {
type: 'string',
format: 'binary',
},
},
},
})
@UseInterceptors(
FileInterceptor('file', {
dest: './uploads', // 서버에 uploads폴더를 자동 생성(이안에 다운 받은 파일이 저장)
}),
)
async downloadFile(
// 다운로드 받은 파일 속성
@UploadedFile('file') file,
// A3 Bucket에 업로드시 사용할 파일 이름
@Query('uploadFileName') uploadFileName: string,
) {
// file["savename"]에 업로드시 지정할 파일 이름을 저장한다.
file['savename'] = uploadFileName;
// file["buffer"]에 업로드할 파일의 버퍼를 저장한다.
file['buffer'] = this.awsService.convertBinary(file.filename);
console.log('file data : ', file);

// 해당 file을 AWS Bucket에 업로드 하고 결과를 data변수에 저장한다.
const data = await this.awsService.uploadFile(file);

// 버퍼로 다운받은 파일을 삭제합니다.
console.log(this.awsService.remove(file['filename']));

// data변수를 클라이언트 쪽에 전달한다.
return data;
}
}

코드2) 컨트롤 부분 작성


코드1,2는 기본적으로 클라이언트로부터 파일을 받아서 uploads폴더에 저장합니다. 그후에 AWS Bucket으로 저장할 이름과 같이 보내고 클라이언트로부터 받은 파일은 삭제합니다.


사진1) Swagger를 이용하여 NestJS서버로 파일 올리기


사진2) 정상 upload


이후 사진1,2에서 Swagger를 통해서 정상 동작 되는 것을 알수 있습니다. 실행되는 코드를 보고 싶으시면 아래 GitHub링크를 참고해 주시기 바랍니다.


GitHub Branch(uploadDirClient) URL


다음글 : NestJS AWS S3버킷에 저장되어있는 파일을 서버에 저장하기 - 3: S3 Bucket의 파일을 다운로드 하기














댓글

이 블로그의 인기 게시물

Lesson 12_1 프로퍼티 노드(Property Node)

DAQ로 전압 측정하기-2

Nest JS URL에 있는 쿼리(Query) 읽기