지난 1편에서는 곰터뷰에 대한 간단한 설명과 곰터뷰에서 Object Storage로 왜 IDrive e2를 사용하게 되었는지 포스팅을 했었다.
그리고 지난번 포스트였던 2편에서는 곰터뷰에서 어떤 로직을 통해 IDrive e2에 비디오를 저장하고, 이를 어떤 로직으로 서비스에서 사용할 수 있게 했는지 포스팅해보았다.
이번에는 IDrive e2 관련 마지막 포스팅으로 그렇다면 어떤 방식으로 구현을 실제로 진행하였는지, 코드를 보며 설명을 진행해보겠다.
1편에서 언급했듯이 IDrive e2는 AWS S3 대체 서비스로 아주 저렴한 가격으로 S3와 동일한 기능을 사용할 수 있다. 그렇기에 토이 프로젝트에서 저렴한 가격으로 Object Storage Service를 사용하고 싶은 사람들에게 이 글이 도움이 되었으면 좋겠다.
IDrive 사용 시에 맞닥뜨린 문제들
우선 IDrive e2는 1편에서 언급했듯이 AWS S3 대체 서비스이고, 그렇기에 AWS에서 제공하는 S3 관련 라이브러리를 사용해서 편리하게 마치 AWS S3를 사용하는 것처럼 쉽게 사용할 수 있다!
우선 서비스를 JavaScript(TypeScript)를 사용해서 구현해야했기에, IDrive e2 공식문서를 들어가서 확인해보았다. 하지만 아래에 언급한 두 가지 부분이 문제점이 있었다.
1. IDrive e2의 공식 문서는 너무 빈약하다.
IDrive e2의 공식 문서는 AWS cli, JavaScript 등 다양한 언어에 대한 사용법을 담고 있었다. 하지만 정말로 너무 간단한 버킷, 파일에 대한 CRUD 기능만 설명하고 있었고, 애초에 JavaScript의 경우에는 코드 예시조차도 못 불러오는 경우가 있었다.
2. IDrive e2의 공식 문서의 내용은 최근 버전인 v3가 아닌 2023년에 deprecated된 v2이다.
공식 문서의 내용을 따라 아주 간단한 코드를 작성하고 실행해보니, 프로그램을 실행하자마자 2023년에 v2가 deprecated 됐다는 충격적인 내용을 확인할 수 있었다. 아직 사용을 못하는 것은 아니기에 큰 문제는 아니었지만, 곰터뷰 서비스를 오랫동안 운영해보고 싶기에 deprecated된 경우라면 무조건 v3로 마이그레이션 하는 것이 필수적이라고 여겨졌다.
AWS S3 SDK for JavaScript
위의 이유들 때문에 비디오 업로드 로직에 어려움이 있을 것으로 예상하였고, 역시나 쉽지 않은 여정이었다. AWS S3 SDK for JavaScript v3의 공식 문서 마저도 정리가 깔끔하게 되지 않고, 전체적인 내용이 모두 한 번에 존재하는 느낌이 들어서 필요한 정보만을 찾아내는데 어려움이 있었다.
또 다른 문제점으로는 IDrive e2는 AWS S3가 아니기에 공식 문서에 적혀있는 내용과 조금 다르게 작성해야 올바르게 작동하는 문제가 있었다.
어쨌든 그래도 AWS S3 SDK for JavaScript v3를 통해 IDrive e2라는 새롭게 접하고, 참고할 자료도 많이 없고, 관련 공식 문서마저 부실한 서비스를 AWS S3를 쓰는 방법대로 그나마 쉽게 사용할 수 있었다.
S3 Client 구성
import 'dotenv/config';
export const IDRIVE_CONFIG = {
region: 'e2',
endpoint: process.env.IDRIVE_ENDPOINT,
credentials: {
accessKeyId: process.env.IDRIVE_ACCESS_KEY_ID,
secretAccessKey: process.env.IDRIVE_SECRET_ACCESS_KEY,
},
};
S3 Client에 설정해야 할 기본 로직이다. 어렵지 않은 객체에 대한 설명이기에 간단하게만 설명해보겠다.
1. 현재 지역(region)으로 'e2'를 설정한다.
2. endpoint(IDrive e2를 사용할 때 요청할 수 있는 API의 엔드포인트)를 'https:// + IDrive에서 버킷에 할당해준 endpoint'로 설정한다. => v3의 AWS S3 SDK 공식 문서에서는 endpoint에 대한 명시를 해놓지 않았으나 IDrive라는 외부 서비스를 사용하기에 직접 명시가 필요하다. 또한 https://를 앞에 prefix로 붙이는 것은 기존 v2 로직과의 차이점이다.
3. credentials를 사용해 S3 Client가 설정해둔 지역과 endpoint를 가진 서버에 권한이 있다는 것을 확인할 수 있다. accessKeyId와 secretAccessKey는 IDrive에서 버킷을 생성할 때 제공된다.
S3 Client를 사용한 Pre-Signed Url 발급 메서드 구현
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { IDRIVE_CONFIG } from 'src/config/idrive.config';
let s3Client: S3Client; // 싱글톤으로 유지할 S3 Client 인스턴스
const getIdriveS3Client = (): S3Client => { // S3 Client를 싱글톤으로 생성하는 메서드
if (!s3Client) {
s3Client = new S3Client(IDRIVE_CONFIG);
}
return s3Client;
};
const getPutCommandObject = (key: string): PutObjectCommand => // Put 요청을 위한 Pre-Signed URL을 생성하는 메서드에서 사용하기 위한 PutObjectCommand를 생성하는 메서드
new PutObjectCommand({ Bucket: 'videos', Key: key });
export async function getSignedUrlWithKey(key: string) { // 특정 key(파일명)를 서버에 업로드 할 수 있게 하는 Put Pre-Signed URL 생성하는 메서드
const s3 = getIdriveS3Client();
const command = getPutCommandObject(key);
const expiresIn = 10;
return await getSignedUrl(s3, command, { expiresIn });
}
v2와 크게 달라진 점이 PutCommandObject를 생성하고, 이를 사용하여 Pre-Signed URL을 만든다는 것이다.
key는 저장될 파일의 이름, bucket은 파일을 저장할 버킷의 이름이다.
위의 메서드를 사용한 Pre-Signed Url 발급
async getPreSignedUrl(member: Member) {
// validateManipulatedToken(member);
const key = `${uuidv4()}.mp4`;
try {
const preSignedUrl = await getSignedUrlWithKey(key);
return new PreSignedUrlResponse(preSignedUrl, key); // 커스텀 응답 객체에 넣어 클라이언트에 반환
} catch (error) {
throw new IDriveException();
}
}
위와 같은 방식으로 진행하였다.
원래는 v2를 사용한 코드 작성과 테스트, 실제 배포 서버에서 사용까지 모두 완료했었으나, 서비스 안정성이나 유지 기간을 고려하였을 때 v3로 변경하자는 생각이 들어, 천천히 마이그레이션을 진행하였다. 이는 서비스 개발자로써 좋은 생각이었다고 생각한다.
Pre-Signed URL을 사용한 비디오 업로드 로직
이전 2편에서 설명했던 내용이지만, Postman을 사용하여 테스트 하는 방법까지 추가하여 설명을 진행해보겠다.
전체적인 흐름은 위의 사진과 같다.
서버에 클라이언트가 Pre-Signed URL 요청
위에서 구현한 getPreSignedUrl 메서드를 서버의 Pre-Signed 요청 엔드포인트에 연결시켜두어, 클라이언트가 업로드를 원할 때마다 발급 받을 수 있도록 하였다.
발급받은 URL로 IDrive e2에 비디오 업로드
다음으로 위의 사진처럼 Pre-Signed URL 발급 요청의 응답으로 들어온 preSignedUrl을 사용하여 Patch 메서드로 업로드를 진행하면, IDrive e2 버킷 상에서 업로드된 파일을 확인할 수 있다.
위의 과정을 거쳐 곰터뷰에서는 비디오 업로드 로직을 구현하였다.
비디오 소비 로직은 DB에 IDrive e2 상의 비디오 URL을 저장해두어 이를 필요할 때마다 요청하여 비디오를 볼 수 있게 업로드보다 훨씬 간단한 방식으로 구현하였다. 비디오 소비의 경우에도 get 요청에 대한 preSignedUrl을 생성할 수 있으니 필요에 따라 참고하여 이용하면 좋을 것 같다.
AWS S3의 라이브러리 신규 버전과 외부 서비스를 동시에 사용하여 구현하는 특이한 상황이었기에 참고할만한 레퍼런스가 부족하여서 조금 어려움을 겪기도 하였지만 프로젝트의 핵심 로직을 잘 구현한 것 같아 기쁘다.
Reference
'개발 > 곰터뷰🐻' 카테고리의 다른 글
단위 테스트(Unit Test)와 통합 테스트(Integration Test) (0) | 2024.01.27 |
---|---|
테스트 코드는 왜 만들까? (3) | 2024.01.19 |
곰터뷰와 IDrive e2 (2) - IDrive e2를 사용한 비디오 저장/조회 로직 (0) | 2023.12.06 |
곰터뷰와 IDrive e2 (1) - 왜 IDrive e2를 사용하게 되었나? (0) | 2023.11.18 |