Lambda 함수를 사용하여 DynamoDB에서 제품을 삽입, 읽기, 업데이트 및 삭제하는 실습
<전체적인 프로세스>
- DynamoDB : AWS Database
- Lambda : DynamoDB에 데이터를 Push하는 FaaS (Function as a Service) 서비스
- API Gateway : 클라이언트(Postman)은 이 AWS 서비스의 도움으로 Lambda와 상호작용
Create Serverless REST APIs using - AWS Lambda, DynamoDB, API Gateway, JavaScript
→ In this article, we create an AWS serverless REST API using Lambda, DynamoDB, API Gateway (three AWS services), and JavaScript
aws.plainenglish.io
1. DynamoDB
;Serverless 데이터베이스로, 데이터를 저장할 제품 table을 생성
테이블 이름과 기본 키 작성
테이블 생성 완료
2. Lambda
;새로운 역할을 가진 Node.js 기술로 빈 Lambda 함수를 생성
;Cloudwatchlogs 및 DynamoDB 전체 액세스라는 두 가지 정책을 첨부
;Lambda 함수의 로직은 로컬 코드 편집기의 JavaScript 파일에서 작성
람다 함수 이름 작성
aws-sdk 모델 import 오류를 막기 위해 Node.js 버전 16.xxx로 다운그레이드 해주기
기본 실행 역할 변경에서 새 역할 생성 후 역할 이름 설정
람다 함수 생성 완료
람다 함수에 정책 연결을 하기 위해
구성->권한 탭 들어가기
역할 이름 들어가준다음에 권한 추가에서 정책 연결 클릭
CloudWatchLogsFullAccess와 AmazonDynamoDBFullAccess 권한 추가
3. API Gateway
;Javascript/Lambda 코드는 DynamoDB와 직접 상호작용 불가 -> 이를 위해서 aws 서비스가 필요
;API Gateway는 JavaScript 코드가 람다 함수를 연결하고 실행할 수 있는 REST 환경을 생성
;API Gateway를 통해 *리소스를 생성할 수 있음
*리소스: API 앤드포인트를 의미 -> 리소스의 각 메서드는 postman에서 실행할 URL
3번째 REST API 선택
새 API 생성 후 이름 지정
이제 각 리소스생성 + 각 리소스에 대한 메서드를 생성해줌
API 상태 확인용인 /health 리소스 만들기
리소스 선택 -> 작업 클릭 -> 메서드 생성 클릭해서 방법 유형 선택
각 메서드는 람다 함수에서 트리거 됨
예) GET 유형, 여기서는 람다 함수로 구성, 나중에 람다 함수를 사용하여 이 메서드를 호출함
통합 유형: 람다 함수
람다 프록시 통합 사용 선택하고 가장 가까운 리전 선택한 다음 최근에 생성된 람다 함수 선택 후 저장
실습할 애플리케이션에서는 여러 엔드포인트가 필요하고
모두 제품의 CRUD에 대한 논리를 작성하는 람다로 구성됨
이렇게 리소스와 메서드를 위와 같은 방식으로 다 만들어 줌
작업 -> API 배포 클릭
스테이지 탭에서 beta 이름 설정 후 배포
모든 API 메서드는 하나의 엔드포인트를 제공함
람다 함수로 구성된 엔드포인트가 준비됨
이제 각 엔드포인트를 호출할 람다 코드를 작성해야함
4. JavaScript
const AWS = require("aws-sdk");
const AWS_REGION = "ap-northeast-2";
AWS.config.update({
region: AWS_REGION,
});
const dynamoDB = new AWS.DynamoDB.DocumentClient();
const dynamoDBTableName = "product-inventory";
// Resources(endpoints) created in API Gateway
const healthPath = "/health";
const productPath = "/product";
const productsPath = "/products";
exports.handler = async function (event) {
console.log("Request event" + event);
let response;
switch (true) {
case event.httpMethod === "GET" && event.path === healthPath:
response = buildResponse(200);
break;
case event.httpMethod === "GET" && event.path === productPath:
response = await getProduct(event.queryStringParameters.productId);
break;
case event.httpMethod === "GET" && event.path === productsPath:
response = await getProducts();
break;
case event.httpMethod === "POST" && event.path === productPath:
response = await saveProduct(JSON.parse(event.body));
break;
case event.httpMethod === "PATCH" && event.path === productPath:
const requestBody = JSON.parse(event.body);
response = await modifyProduct(
requestBody.productId,
requestBody.updateKey,
requestBody.updateValue
);
break;
case event.httpMethod === "DELETE" && event.path === productPath:
response = await deleteProduct(JSON.parse(event.body).productId);
break;
default:
response = buildResponse(404, "404 Not Found");
}
return response;
};
// Get Specific Product
async function getProduct(productId) {
const params = {
TableName: dynamoDBTableName,
Key: {
productId: productId,
},
};
return await dynamoDB
.get(params)
.promise()
.then((response) => {
return buildResponse(200, response.Item);
},
(err) => console.log("ERROR: ", err)
);
}
// Gets all products
async function getProducts() {
const params = { TableName: dynamoDBTableName };
const allProducts = await scanDynamoRecords(params, []);
const body = {
products: allProducts,
};
return buildResponse(200, body);
}
async function scanDynamoRecords(scanParams, itemArray) {
try {
// Read Dynamo DB data, pushing into array
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 (err) {
console.log("ERROR in Scan Dynamo Records: ", err);
}
}
// Add a Product
async function saveProduct(requestBody) {
const params = {
TableName: dynamoDBTableName,
Item: requestBody,
};
return await dynamoDB
.put(params)
.promise()
.then(() => {
const body = {
Operation: "SAVE",
Message: "SUCCESS",
Item: requestBody,
};
return buildResponse(200, body);
},(err) => {
console.log("ERROR in Save Product: ", err);
}
);
}
async function modifyProduct(productId, updateKey, updateValue) {
const params = {
TableName: dynamoDBTableName,
Key: {
productId: productId,
},
UpdateExpression: `set ${updateKey} = :value`,
ExpressionAttributeValues: {
":value": updateValue,
},
ReturnValues: "UPDATED_NEW",
};
return await dynamoDB
.update(params)
.promise()
.then(
(response) => {
const body = {
Operation: "UPDATE",
Message: "SUCCESS",
UpdatedAttributes: response,
};
return buildResponse(200, body);
}, (err) => {
console.log("ERROR in Update Product: ", err);
}
);
}
// Delete a Product
async function deleteProduct(productId) {
const params = {
TableName: dynamoDBTableName,
Key: {
productId: productId,
},
ReturnValues: "ALL_OLD",
};
return await dynamoDB
.delete(params)
.promise()
.then((response) => {
const body = {
Operation: "DELETE",
Message: "SUCCESS",
Item: response,
};
return buildResponse(200, body);
},
(err) => {
console.log("ERROR in Delete Product: ", err);
}
);
}
// For specific response structure
function buildResponse(statusCode, body) {
return {
statusCode,
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
};
}
위 코드를 복사하여
람다 함수에 붙여넣고 테스트 및 배포 클릭
테스트 뜰 때 이런 게 나오는데
대강 이렇게 설정하고 저장해줬다...
배포했는데
statusCode가 성공적인 200이 아니고 404로 떠서 어라 싶었는데
5. Postman
;API 확인을 해보자
포스트맨 처음 써봐서
저기 New 누르고 HTTP 들어가줌
POST - 상품 추가 API
{
"productId": "103",
"productName": "Nescafe Classic",
"price": 50,
"color": "classic",
"inventory": 2000
}
이거 복붙해서 Body 데이터에 넣고 Send 해주면
밑에 성공적으로 정보가 뜬다!
HTTP 메소드 중에서 POST는 서버한테 데이터 처리해달라는 거여서 body에 데이터 같이 보내줘야 한다고 함!!!
GET - 상품 조회 API
productID=103 key-value값 넣어준 다음 Send 해주면
이녀석도 정보가 잘 뜬다

예이 잘 돼서 신남
근데 이제 404 뜨는 이유를 다시 찾아봐야...
'클라우드 > AWS' 카테고리의 다른 글
[AWS] 리소스 일괄 삭제, aws-nuke (+다른 리소스 삭제소스: cloud-nuke? resoto?) (1) | 2023.08.05 |
---|---|
무에서 시작하는 AWS SDK 설치 (0) | 2023.08.02 |
[AWS] 데이터베이스- DynamoDB (0) | 2023.07.25 |
[AWS] Edge Location - Global Accelerator (0) | 2023.07.24 |
[AWS] Computing Service / LightSail, EC2 (0) | 2023.07.13 |