Example Lambda Nodejs Api Gateway With Dynamodb
아래와 같은 환경으로 serverless 환경을 구성하기 위한 예제이다.
┌─────────────┐ ┌── lambda ──┐ ┌──────────┐
│ api-gateway ├──────┤ nodejs ├──────┤ dynamodb │
└─────────────┘ └────────────┘ └──────────┘
dynamodb
dynamodb 는 아래와 같이 구성히고 샘플 데이터도 사전에 넣어 두자.
- tableName :
SampleTableName
- partition key :
id
- sort key :
startDate
SampleTableName
┌─── Sort Key
┌─────┬──┴────────┬──────────┬──────────────────┐
│ id │ startDate │ endDate │ contents │
├─────┼───────────┼──────────┼──────────────────┤
│0001 │20210101 │20210115 │ first contents │
├─────┼───────────┼──────────┼──────────────────┤
│0002 │20210102 │20210220 │ second contents │
└─┬───┴───────────┴──────────┴──────────────────┘
└─ Partition Key
lambda
중간에 있는 lambda 예제는 아래와 같이 구성한다.
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const tableName = 'SampleTableName';
const healthPath = '/health'
const noticePath = '/notice'
exports.handler = async function(event) {
let response;
switch (true) {
case event.httpMethod === 'GET' && event.path === healthPath:
response = buildResponse(200, 'ok');
break;
case event.httpMethod === 'GET' && event.path === noticePath && event.queryStringParameters !== null:
response = getNotice(event.queryStringParameters.id, event.queryStringParameters.startDate);
break;
case event.httpMethod === 'GET' && event.path === noticePath:
response = searchNotice();
break;
case event.httpMethod === 'POST' && event.path === noticePath:
response = saveNotice(JSON.parse(event.body));
break;
case event.httpMethod === 'PATCH' && event.path === noticePath:
const requestBody = JSON.parse(event.body);
response = modifyNotice(requestBody.id, requestBody.startDate, requestBody.updateKey, requestBody.updateValue);
break;
case event.httpMethod === 'DELETE' && event.path === noticePath:
response = deleteNotice(JSON.parse(event.body).id, JSON.parse(event.body).startDate);
break;
default:
response = buildResponse(404, 'something wrong!');
}
return response;
}
async function deleteNotice(id, startDate) {
const params = {
TableName: tableName,
Key: {
id: id,
startDate: startDate
},
ReturnValues: 'ALL_OLD'
}
return await dynamodb.delete(params).promise().then((response) => {
const body = {
Operation: 'DELETE',
Message: 'SUCCESS',
Item: response
}
return buildResponse(200, body);
}, (error) => {
console.error('삭제 오류 발생:', error);
});
}
async function modifyNotice(id, startDate, updateKey, updateValue) {
const params = {
TableName: tableName,
Key: {
id: id,
startDate: startDate
},
UpdateExpression: `set ${updateKey} = :value`,
ExpressionAttributeValues: {
':value': updateValue
},
ReturnValues: 'UPDATED_NEW'
}
return await dynamodb.update(params).promise().then((response) => {
const body = {
Operation: 'UPDATE',
Message: 'SUCCESS',
Item: response
}
return buildResponse(200, body);
}, (error) => {
console.error('수정 에러', error);
});
}
async function getNotice(id, startDate) {
const params = {
TableName: tableName,
Key: {
id: id,
startDate: startDate
}
}
return await dynamodb.get(params).promise().then((response) => {
return buildResponse(200, response.Item)
}, (error)=> {
console.error('찾고자 하는 데이터가 없음', error);
});
}
async function searchNotice() {
const params = {
TableName: tableName
}
const allNotice = await scanDynamoRecords(params, []);
const body = {
notices: allNotice
}
return buildResponse(200, body);
}
async function scanDynamoRecords(scanParams, itemArray) {
try {
const dynamoData = await dynamodb.scan(scanParams).promise();
itemArray = itemArray.concat(dynamoData.Items);
if (dynamoData.LastEvaluatedKey) {
scanParams.ExclusiveStartKey = dynamoData.LastEvaluatedKey;
return await scanDynamoRecords(scanParams, itemArray)
}
return itemArray;
} catch (error) {
console.error('조회 오류 발생', error);
}
}
async function saveNotice(requestBody) {
const params = {
TableName: tableName,
Item: requestBody
}
return await dynamodb.put(params).promise().then(() => {
const body = {
Operation: 'SAVE',
Message: 'SUCCESS',
Item: requestBody
}
return buildResponse(200, body);
}, (error) => {
console.error('저장 오류 발생', error);
});
}
function buildResponse(statusCode, body) {
return {
statusCode: statusCode,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
}
api gateway
이제 api gateway 를 아래와 같이 구성하고 각 메소드는 위의 lambda 와 연결한다. (주의할 것은 아래 것임)
- Integration type :
Lambda Function
- Use Lambda Proxy integration :
V
- Lambda Region :
lambda-region
- Lambda Function :
my-lambda-name
/
/health
GET
OPTIONS
/notice
DELETE
GET
OPTIONS
PATCH
POST
api gateway 테스트를 수행하여 확인하면 된다.
Read other posts