AWS Simple Storage Service(S3)
데이터를 버킷 내의 객체로 저장하는 객체 스토리지 서비스
AWS S3 에 저장된 객체에 대한 컨테이너
S3 에 저장되는 기본 객체
객체는 객체 데이터와 메타 데이터로 구성된다.
- 메타 데이터 : 객체를 설명하는 이름-값 쌍의 집합 (ex. 마지막으로 수정한 날짜와 같은 기본 메타데이터, content-type 같은 표준 HTTP 메타데이터)
- 표준 HTTP 메타 데이터:
객체는 키(이름), 버전 ID 를 통해 식별된다.
웹 서비스 엔드포인트, 버킷 이름, 키, 버전의 조합을 통해 고유하게 주소를 지정할 수 있다.
ex) 미국 서부 리전에서 생성된 DOC-EXAMPLE-BUCKET
라는 버킷에 저장된 photos/puppy.jpg
라는 객체의 URL 은 https://DOC-EXAMPLE-BUCKET.s3.us-west-2.amazonaws.com/photos/puppy.jpg
즉 https://[버킷 이름].s3.[리전 이름].amazonaws.com/[키]
S3 버전 관리를 사용하여 동일한 버킷 내에서 여러개의 객체 변형을 가질 수 있으며, 검색 및 복원이 가능하다.
데이터에 액세스 할 수 있는 네트워크 엔드 포인트
버킷을 저장할 지리적 AWS 지역을 의미
https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/create-bucket-overview.html
multer-s3
AWS-SDK
: AWS를 프로그래밍적으로 제어하기 편리하도록 제공되는 라이브러리들을 의미한다. REST API 를 wrapping 하는 형태다.npm install aws-sdk multer-s3
// s3.json
{
"accessKeyId": "엑세스 키",
"secretAccessKey": "시크릿 엑세스 키",
"region": "ap-northeast-2"
}
//imgAPI.ts
import multerS3 from 'multer-s3';
import aws from 'aws-sdk';
// aws config 파일 읽기
aws.config.loadFromPath('s3.json');
// s3 객체 생성
const s3 = new aws.S3();
// multer 에 대한 설정값
const awsUpload = multer({
storage: multerS3({
s3: s3,
bucket: 'bevelog-bucket', // 객체를 업로드할 버킷 이름
acl: 'public-read', // Access control for the file
key: function (req, file, cb) { // 객체의 키로 고유한 식별자 이기 때문에 겹치면 안됨
cb(null, Math.floor(Math.random() * 1000).toString() + Date.now() + '.' + file.originalname.split('.').pop());
}
}),
});
router.post('/images/:username/thumbnail', awsUpload.single('thumbnail'), (req, response) => {
// 코드 중략
})
multer.single(fileName)
: fileName 으로 명시된 이름의 파일을 전달받아 req.file 에 저장해 다음(next()) 로 넘겨주는 역할을 한다.
req.file
을 조회해 보면 location 속성에 버킷에 저장된 객체의 URL 이 담긴다.
여기까지만 해도 버킷에 이미지가 업로드된 것을 확인할 수 있다.
추후 S3 버킷에 저장된 이미지를 다운로드에 클라이언트에 전달해주기 위해, THUMBNAIL_IMAGES
테이블을 생성하고 버킷에 저장된 객체를 가져오기 위한 정보들을 저장해줘야한다.
따라서 THUMBNNAIL_IMAGES
table 에 insert 할 정보는
INSERT INTO public."THUMBNAIL_IMAGES" ('id','fk_user_name', 'path', 'file_size')
VALUES (`${req.file.key}`, `${req.params.username}`, `${req.file.location}`, `${req.file.size}`)