진행중인 프로젝트에서 이미지 저장용으로 S3를 사용해보려고 한다.
S3 뜻은 별거없다 Simple Storage Service. S가 3개라... S3....
이미지 업로드에서 중점적으로 고민하고 있는 부분 중 하나는 서버에 I/O작업을 줄이고 최대한 부하를 덜어내는 방향을 우선적으로 채택하는 것이다. 현재 상황에서는 소켓통신과 실시간 위치계산 등으로 앞으로도 더 많은 resource가 서버에서 필요할 것 으로 예상되고 데이터 전송의 Cost도 만만치 않다.
그래서 이미지 관련해서는 Client browser에서 직접 S3로 업로드 하고 url 만 RDB에 저장하는 방식을 사용해보기로 했다.
express 에서 multer를 사용하여 Client쪽에서 서버로 이미지를 먼저 보내고, 서버에서 S3로 업로드 하는 방법은 다른 상황에서 사용되어야 할 것 같다.
문제는 S3 AWS접근 권한을 Server만 가지고 있는 부분이었다 업로드는 클라이언트가 해야하는데 권한을 그대로 넘겨주면 안된다. 찾아보다가 AWS-SDK에서 관련하여 지원하는 방식이 있었다. 서명된 url을 클라이언트에서 요청하고 일정 시간내에 업로드하고 url주소를 DBV에 저장하는 방식을 사용할 수 있었다. 아래 그림과 같다.
const handleSubmit = async (e) => {
e.preventDefault();
//1. 서버로부터 서명된 URL 요청
const res = await api.get("/main/s3Url");
console.log("url", res.data.url);
const { url } = res.data;
console.log(url);
//2. post the image direclty to the s3 bucket
if (authImage) {
await fetch(url, {
method: "PUT",
headers: {
"Content-Type": "multipart/form-data",
},
body: authImage[0],
});
}
const imageUrl = url.split("?")[0];
console.log(imageUrl);
const resp = {
user_info_id: alien.alien.user_info_id,
Alien_id: alien.alien.id,
Challenge_id: alien.alien.Challenge_id,
comment: authMessage,
imgURL: imageUrl,
};
//3. post requst to my server to store any extra data
const result = await api.post("/challenge/auth", resp); //
console.log(result);
};
S3에서 Object는 Key로 식별할 수 있다.
The object key (or key name) uniquely identifies the object in an Amazon S3 bucket. Object metadata is a set of name-value pairs. For more information about object metadata, see Working with object metadata. When you create an object, you specify the key name, which uniquely identifies the object in the bucket.
새로운 이미지 upload와 update API는 비슷하지만 살짝 다른 방식으로 구현해보려고 한다.
지금 우선 고민되는 부분은
1. 서명된 url 요청시 createPresignedPost 를 사용할지, getSignedUrl을 사용하여 url을 생성할지.
createPresignedPost가 조금 더 요청을 customizing가능하지만 Client쪽에서 해줘야 하는 것들이 있다. 가능한 Client쪽에서 최소정보만 가지고 업로드 가능하도록 하면서 리소스에 대한 정보는 노출되지 않는 방향으로 해보려고 한다.
2. client쪽에서 이미지 접근시 Cloudfront를 이용하게 할지, 퍼블릭으로 image접근이 가능하도록 할지.
+추가 (11.18)
사실 더 고민했어야 하는 방향은 어떤식으로 이미지를 resizing 해야 하는지였다. 왜냐하면 현재 상황에서는 불필요하게 고용량의 사진들이 나의 S3에 끊임없이 저장되기 때문이다. 비용적인측면, 사진 다운로드 속도 측면에서 비효율 적이다.
사실 실제로 서비스 운영에 필요한 이미지 용량은 1/5~1/10 정도에 불과하다.
이 부분은 지금 알고있는 바로는 3가지 정도 옵션이 있는데,
하나는 Image proxy 서버로 리사이징 하는것
두번째는 Image size를 validation하는 로직을 만들어서 client가 제한 용량을 초과하는 이미지를 업로드하려고 하면 반려하는 방법
세번째는 그냥 무지성으로 다 업로드하게 허용하고 이미지 로드시 리사이징 하는법
세번째가 제일 쉽다 근데 돈이 쫌 나갈 수도 있다... 어차피 바뀌어야 하는 방향인듯..
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createPresignedPost-property
https://github.com/codyseibert/youtube/blob/master/s3-upload-example/index.html
https://s3.console.aws.amazon.com/s3/object/namu-alien-s3?region=ap-northeast-2&prefix=namu-alien
'프로젝트' 카테고리의 다른 글
간단한 채팅구현 Socket.io (Node js) (0) | 2021.11.22 |
---|---|
MYSQL TRIGER (0) | 2021.11.18 |
로그인 기능 적용과 몇 일간의 뻘짓 (feat . CORS (Cross-Origin Resource Sharing) ) (0) | 2021.11.15 |
DB 최적화 읽을거리 (0) | 2021.11.11 |
서버 API 작성시 알아야 할 내용 (request, DB, SQL) (0) | 2021.11.11 |