[Express] AWS S3(Simple Storage Service) 에 이미지 업로드와 다운로드 해보기

Ahnjh·2022년 10월 20일
0

Express

목록 보기
5/5

들어가기에 앞서 S3가 무엇인지 알아보자면

(이번 포스트에서는 aws s3 버킷 생성은 다루지 않는다)

S3(Simple Storage Service) 란 ?

Amazon Simple Storage Service(Amazon S3)는 업계 최고의 확장성, 데이터 가용성, 보안 및 성능을 제공하는 객체 스토리지 서비스입니다. 모든 규모와 업종의 고객은 Amazon S3를 사용하여 데이터 레이크, 웹 사이트, 모바일 애플리케이션, 백업 및 복원, 아카이브, 엔터프라이즈 애플리케이션, IoT 디바이스, 빅 데이터 분석 등 다양한 사용 사례에서 원하는 양의 데이터를 저장하고 보호할 수 있습니다. Amazon S3는 특정 비즈니스, 조직 및 규정 준수 요구 사항에 맞게 데이터에 대한 액세스를 최적화, 구조화 및 구성할 수 있는 관리 기능을 제공합니다.

S3 의 기능

  • 스토리지 클래스 : 액세스 빈도가 높고 낮음에 따라 가격이 비례하는 저장소를 선택할 수 있다
  • 스토리지 관리
    • 수명주기 : 수명 주기 정책을 구성해 저장된 객체의 비용을 효율적으로 저장할 수 있다.
    • 객체 잠금 : 고정된 시간동안 객체의 삭제나 덮어쓰기를 방지할 수 있다
    • 복제 : 객체에 대한것들을 다른 aws 버킷에 복제할 수 있다
    • 배치작업 : 배치작업을 사용하여 수백만 또는 수십억개의 객체를 복사, Lambda 함수 호출 및 복원등의 작업을 할 수 있다

종속성 설치

$ npm install aws-sdk
$ npm install uuid

환경변수 구성

AWS_ACCESS_KEY=`${YOUR_ACCESS_KEY}`
AWS_SCRET_ACCESS_KEY=`${YOUR_SCRET_ACCESS_KEY}`
AWS_REGION=ap-northeast-2
AWS_BUCKET=`${YOUR_BUCKET}`

REGION은 지역을 뜻하는데 ap-norheast-2 는 한국 서울을 뜻한다. 서울 리전이라고 해서 서버가 서울에 있을때만 저렇게 적는것이 아닌 단지 한국 대표지역의 이름을 딴것이다.

코드 이름 옵트인 상태
us-east-2 US East (Ohio) 불필요
us-east-1 미국 동부(버지니아 북부) 불필요
us-west-1 미국 서부(캘리포니아 북부) 불필요
us-west-2 미국 서부(오리건) 불필요
af-south-1 아프리카(케이프타운) 필수
ap-east-1 아시아 태평양(홍콩) 필수
ap-southeast-3 아시아 태평양(자카르타) 필수
ap-south-1 아시아 태평양(뭄바이) 불필요
ap-northeast-3 아시아 태평양(오사카) 불필요
ap-northeast-2 아시아 태평양(서울) 불필요
ap-southeast-1 아시아 태평양(싱가포르) 불필요
ap-southeast-2 아시아 태평양(시드니) 불필요
ap-northeast-1 아시아 태평양(도쿄) 불필요
ca-central-1 캐나다(중부) 불필요
eu-central-1 유럽(프랑크푸르트) 불필요
eu-west-1 유럽(아일랜드) 불필요
eu-west-2 유럽(런던) 불필요
eu-south-1 유럽(밀라노) 필수
eu-west-3 유럽(파리) 불필요
eu-north-1 유럽(스톡홀름) 불필요
me-south-1 중동(바레인) 필수
me-central-1 중동(UAE) 필수
sa-east-1 남아메리카(상파울루) 불필요

s3 에 업로드 시켜보기!

앞단에서 "img" 란 이름의 객체를 넘겨준다고 가정한 후 작성한 코드이다

router.post("/awsTest",(async (req, res) => {
  const aws = require("aws-sdk");
  const img = req.get('img');
  const imgPath = img.path;
  const imgName = img.name;

  const s3 = new aws.S3({
      region: process.env.AWS_REGION,
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SCRET_KEY,
      s3ForcePathStyle: true,
  });

  s3.upload({Bucket: bucket, Key: fileName, Body: filePath }, async (err, data) => {
    if (err) {
      throw err;
    }

    console.log("S3 Upload Success!");
    console.log(data);
  });

}));

위와같이 코드를 작성하고 테스트를 해보면 아래와 같이 정상적으로 올라간 것을 볼 수 있다

Error: Request aborted

필자는 해당 오류로인해 고생을했는데 프론트단에서 <form> 태그를 작성할때 onSubmit 에 e.preventDefault(); 추가를 안해줘서 생겼었다.
구글링을 하다보니 Button에 타입을 안준사람 등 여러가지 이유가 있는것 같다.

Refactoring

위처럼 작성하고나면 지저분해보이는 코드 탓에 빨리 리팩토링 하고싶은 사람도 있을것이다 필자는 아래와같이 정리했다.

// util/AWSUtil.js

const aws = require("aws-sdk");

const fs = require("fs");

const bucket = process.env.AWS_BUCKET_NAME;

const s3 = new aws.S3({
    region: process.env.AWS_REGION,
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SCRET_KEY,
    s3ForcePathStyle: true,
});

module.exports = {
    s3Upload: (
        fileName,
        filePath,
    ) => {
        try {
            s3.upload({
                Bucket: bucket,
                Key: fileName,
                Body: filePath
            }, async (err, data) => {
                if (err) {
                    throw err;
                }

                console.log("S3 Upload Success!");
                console.log(data);
            });
        } catch (e) {
            console.log(e);
        } finally {
            fs.unlinkSync(filePath);
        }
    },
};
// router
router.post("/awsTest", (async (req, res) => {
    const img = req.get('img');
    const imgPath = img.path;
    const imgName = img.name;

	AWSUtil.s3Upload(imgName, imgPath);
}));

상당히 깔끔해졌다 !!

s3 에서 파일 가져와 보기 !

파일 가져오는것은 위에서했던 올리는것보다 훨씬 더 간단하다

// util/AWSUtil.js

s3getFile: (
        key = "1039983.jpg"
    ) => {
        try {
            s3.getObject({
                Bucket: bucket,
                Key: key
            }, (async (err, data) => {
                if (err) {
                    throw err;
                }

                console.log("!success ");
                console.log(data);
            }));
        } catch (e) {
            console.log(e);
        }
    }
router.get("/awsGetTest", (async (req, res) => {
	AWSUtil.s3getFile();
}));

위에서 만들어줬던 s3Upload 아래에 s3GetFile을 만들어준 후 위와같이 작성해주면 된다 키값은 위에서 올린 파일이름이다.

실행시켜주면 아래처럼 결과가 나오게 된다

profile
Clean Code & Clean Architecture

0개의 댓글