이미지 업로드를 서버에서 하는 것은 좋지 않다. 그 이유는 내 예전 글에서 볼 수 있음
이번에도 똑같이 하려고 했으나 직접 만드는 법을 까먹었다. 전에는 aws 콘솔에서 직접 람다 펑션을 작성해줬었다. 근데 생각해보면 이미지 업로드 펑션을 전세계의 많은 개발자가 이미 구현을 많이 해뒀을 것 같았다. 그래. 내가 만든 덜떨어진 함수보다는 똑똑한 사람들이 이미 만들어둔 걸 쓰는게 낫겠다는 생각이 들었다.
역시 똑똑한 다른 개발자가 만들어둔 샘플이 있었다.
심지어 유튜브에서 설명까지 해줌
샘플 코드는 깃허브에서 확인할 수 있었다.
내가 사용할 샘플 코드는 s3-signed-url이다.
signedUrl을 사용하면 aws 권한이 없는 클라이언트에서도 이미지를 버킷에 업로드 할 수 있다.
다음 샘플코드는 클라의 요청을 처리하는 코드인 셈이다.
handler.js 를 보면
module.exports.createPostUrl = async (event) => {
const client = new S3Client(clientParams);
const Key = `${prePath}${(Math.random() + 1).toString(36).substring(2)}`
const { url, fields } = await createPresignedPost(client, {
Bucket: config.S3_BUCKET,
Key,
Expires: 600, //Seconds before the presigned post expires. 3600 by default.
});
return {
statusCode: 200,
body: JSON.stringify(
{
url,
fields
},
null,
2
),
};
};
쉽다. s3클라이언트를 생성 후, signed url 발급받아서 응답에 포함시켜주는 로직이다
그리고 이 레포를 보면 serverless.yml
이 있는데 이걸 어떻게 사용하는지는 간단히 설명하려 한다.
나는 서버리스가 프레임워크 이름인줄 처음 알았다. 보니까 짱 편해보이더라. 앞으로 람다는 이걸로 올릴 것 같다.
서버리스 프레임워크 사용법은 간단하다.
serverless deploy
명령어 갈기면 배포가 됨..간단히 미리 얘기해보았는데, 조금 더 자세히 보자
npm install -g serverless
serverless 대신 sls 를 사용해도 된다.
설치를 확인하기 위해 버전을 확인해보세요.
sls --version
나는 이미 샘플코드에 yml이 정의 돼있었다. 근데 저게 좀 오래된거라 프레임워크 버전에서 에러가 났다. 난 그냥 주석처리 했다.
service: s3-signed-url
frameworkVersion: '2' # (1) 여기서 에러가 터질것이다.
provider:
name: aws
runtime: nodejs12.x
lambdaHashingVersion: 20201221
stage: ${file(config.json):STAGE}
region: ${file(config.json):REGION}
iamRoleStatements:
- Effect: "Allow"
Action:
- "s3:GetObject"
- "s3:GetObjectVersion"
- "s3:PutObject"
Resource:
- "arn:aws:s3:::${file(config.json):S3_BUCKET}/*"
functions: # 배포 할 함수들
create-get-url: # 이건 내가 쓰진 않을 거라 뺐다. 쓸거면 쓰셈 (사진 조회도 권한 설정이 되어있는 경우 사진 조회하는 url을 얻는 함수)
handler: functions/handler.createGetUrl
events:
- http:
path: /object/{fileKey}
method: get
cors: true
request:
parameters:
paths:
fileKey: true
create-post-url: # presigned url을 반환하는 함수! 내가 사용할 것.
handler: functions/handler.createPostUrl
events:
- http:
path: /upload-url
method: get
cors: true
serverless 프로그램이 우리의 코드를 aws에 배포하기 위해서는 당연히 권한이 필요하다.
이건 그냥 서버리스 공식문서보고 따라하면 된다.
나는 이미 돼있어서 스킵 ㅎㅎ
로컬에서 테스트
serverless invoke local --function create-post-url
진짜 편하다.. 이렇게 하면 배포 전에 로컬로 테스트를 해볼 수 있다.
명령어를 실행해보자구.
잘되는지 확인됐다면, 배포를 해보쟈꾸
서버리스 애플리케이션 배포
sls deploy --aws-profile serverless
잘되면 이렇게 뜸
Deploying s3-signed-url to stage dev (ap-northeast-2)
✔ Service deployed to stack s3-signed-url-dev (142s)
endpoints:
GET - https://pseqcwj9sc.execute-api.ap-northeast-2.amazonaws.com/dev/object/{fileKey}
GET - https://pseqcwj9sc.execute-api.ap-northeast-2.amazonaws.com/dev/upload-url
functions:
create-get-url: s3-signed-url-dev-create-get-url (17 MB)
create-post-url: s3-signed-url-dev-create-post-url (17 MB)
2 deprecations found: run 'serverless doctor' for more details
Monitor all your API routes with Serverless Console: run "serverless --console"
끝임. 진자 끝임 우하하
포스트맨으로 테스트를 해보았다.
handler에 정의 된 것처럼, 람다 요청 url로 get 요청을 보내면 됨.
그러면 이렇게 필요한 정보들이 응답에 온다.
우리는 이제 이 정보들을 헤더에 넣어 s3에 파일을 등록할 수 있다.
파일 생성 요청이라 204로 응답 바디는 없다. 하지만 잘 된 것이니 웃으면 된다.
비록 우리는 포스트맨으로 테스트 했기 때문에 하나하나 입력해줘야 했지만 클라이언트에서 코드로 구현하면 뚝딱이기 때문에 어려운 요청은 아니니 적용해볼 수 있다면 해보기를 추천!