SAM Lambda S3이벤트 트리거, MongoDB 접근코드
Last updated
Last updated
상태: Done 생성일: 2023년 1월 10일 오후 2:18 유형: 코드
nodejs 16 으로 세팅함
bucket 버킷에 test 이미지 파일을 올려놓음
AWS 서비스용 javascript API 를 제공한다.
AWS SDK for JavaScript란 무엇인가요?
const AWS = require('aws-sdk');
const s3 = new AWS.S3(); // https://docs.aws.amazon.com/AmazonS3/latest/API/API_Operations_Amazon_Simple_Storage_Service.html
MongoClient 라이브러리를 사용해 mongodb 에 연결할수있다.
데이터를 검색하는 경우 ObjectId를 사용하기 위해선 라이브러리를 추가로 설치해야한다
const MongoClient = require('mongodb').MongoClient;
const ObjectId = require('mongodb').ObjectId;
mongoose 가 많이 사용되는 라이브러리 같은데 스키마를 사용할 수 있다는게 장점이라고 한다. 여기선 필요없으니 mongodb로 사용해도 충분한것같다.
event에는 객체의 경로에 대한 정보가 포함되어있다.
key가 객체의 경로고 문자열을 split 으로 쪼개서 필요한 폴더의 이름을 추출해 mongodbConnect 함수로 넘겨주었다.
s3.getObject 는 키값으로 버킷에서 해당 객체를 조회한다.
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const MongoClient = require('mongodb').MongoClient;
const ObjectId = require('mongodb').ObjectId;
exports.lambdaHandler = async (event, context) => {
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); //key path 경로
const params = {
Bucket: bucket,
Key: key,
};
//키 경로의 중간부분에 디비에서 id값으로 쓰일 부분을 잘라 넘겨줌
const parts = key.split('/');
const id = parts[2];
try {
//await로 s3객체를 검사한뒤 (동기적으로) mongoDB관련 함수를 실행한다
const { ContentType } = await s3.getObject(params).promise();
await mongodbConnect(`${id}`);
return ContentType;
} catch (err) {
const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
console.log(message);
throw new Error(message);
}
};
MongoDB를 연결하고 필요한 update처리를 한다
async function mongodbConnect(id) {
const url = '[MONGODB_URL]';
const client = new MongoClient(url, { useNewUrlParser: true });
// MongoDB 연결
try {
await client.connect();
console.log('Connected database.');
} catch (err) {
console.log('Failed to connected database.');
}
try {
const db = client.db('[DB]');
const collection = db.collection('[COLLECTION]');
//id 값으로 조회하여 업데이트 원하는 항목을 업데이트함
// 조건
const query = { _id: ObjectId(id)};
// 업데이트
const update = {$set: {status: true}};
// 옵션
const options = { returnOriginal: false };
await collection.findOneAndUpdate(query, update, options);
console.log(id+' Update succeeded');
}catch (err) {
console.log('Failed to update the state of the object. Check if the ObjectId exists in the database.');
}finally {
// MongoDB 연결 해제
client.close();
}
}
CloudFormation 방식으로, 스택이라는 리소스를 생성하며 aws 로 배포가능하게 해줌
템플릿은 자신에게 맞게 잘 작성해주어야함 아래는 그냥 예시임
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
s3lambda
Sample SAM Template for s3lambda
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
MemorySize: 128
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs16.x
Architectures:
- arm64
Policies:
- S3CrudPolicy:
BucketName: !Sub "bucket"
Events:
HelloWorld:
Type: S3 # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Bucket:
Ref: Bucket1
Events: s3:ObjectCreated:*
Bucket1:
Type: AWS::S3::Bucket
# 아래 부분을 추가하여 배포하면 버킷을 새로 생성함
# Properties:
# BucketName: !Sub "bucket"
로컬 테스트용도로 사용함
위와 같이 코드를 작성후 람다를 실행하였을때 content type 을 가져오는걸 확인할 수 있었음
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-west-2",
"eventTime": "1970-01-01T00:00:00.000Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "EXAMPLE"
},
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"responseElements": {
"x-amz-request-id": "EXAMPLE123456789",
"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "testConfigRule",
"bucket": {
"name": "olobo",
"ownerIdentity": {
"principalId": "EXAMPLE"
},
"arn": "arn:aws:s3:::olobo"
},
"object": {
"key": "키경로",
"size": 1024,
"eTag": "0123456789abcdef0123456789abcdef",
"sequencer": "0A1B2C3D4E5F678901"
}
}
}
]
}
참고