昨天我們已經學會如何透過 API Gateway + Lambda 做一個 Hello API,今天要進一步把「資料存下來」,不然每次 API 都只是回傳一個字串,沒辦法保留狀態。這時候我們需要「資料庫」(Database),而 AWS 提供的 NoSQL 服務就是 DynamoDB。
DynamoDB 是 AWS 的全託管 NoSQL 資料庫,特點是:
Step 1:建立 DynamoDB 資料表
打開 DynamoDB Console,並點選「建立資料表」 (Create Table)。
設定:
在我們的例子裡,Partition key 設成 id (String)。其他則保持預設,最後按建立完成,這樣我們就有一張可以存放留言的表格。
Step1:建立 Lambda 函數
我們來到AWS Console → Lambda → Create function
設定:
Function name: MessagesHandler
Runtime: Node.js 20.x(ES module 支援 import 語法)
Permissions: 建立新的 role,選「Create a new role with basic Lambda permissions」
點擊建立後進入 Lambda 編輯頁面,在下方找到「組態」中的環境變數,並建立 key & value
環境變數是程式可以讀取的設定值,讓程式碼不需要硬編碼表名,也方便不同環境(開發/測試/正式)切換。
Step2:設定 Lambda 的 IAM 權限
建立 Lambda 函數時,AWS 會自動幫你建立一個執行角色(Execution Role),這個角色需要有權限操作 DynamoDB,你可以在 IAM Console 中:
找到 Lambda 的角色,附加 Policy AmazonDynamoDBFullAccess
或只給 CRUD 權限(dynamodb:PutItem
, dynamodb:GetItem
, dynamodb:UpdateItem
, dynamodb:DeleteItem
, dynamodb:Scan
)
注意:Lambda 的角色就像程式的身分證,它決定程式能對 AWS 做哪些操作。沒有正確權限,Lambda 就無法操作 DynamoDB。
Step3:撰寫 Lambda 程式碼
這個 Lambda 函數是一個 API 後端服務,專門用來操作 DynamoDB 資料表(Messages),支援四種基本操作,也就是 CRUD:
Lambda 會依據 HTTP 方法判斷要做哪一個操作,並使用 DynamoDB Document Client 與資料表互動。最後,將操作結果以 JSON 回傳給使用者。
// 匯入 AWS SDK v3 套件
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
PutCommand,
GetCommand,
UpdateCommand,
DeleteCommand,
DynamoDBDocumentClient
} from "@aws-sdk/lib-dynamodb";
// 建立 DynamoDB Client
const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);
// Lambda Handler
export const handler = async (event) => {
const tableName = "Messages"; // 你的 DynamoDB 資料表名稱
let body;
let statusCode = 200;
try {
switch (event.httpMethod) {
// ------------------- Create (POST) -------------------
case "POST":
body = JSON.parse(event.body);
await docClient.send(new PutCommand({
TableName: tableName,
Item: { id: body.id, message: body.message }
}));
body = { message: "Item created successfully" };
break;
// ------------------- Read (GET) -------------------
case "GET":
const id = event.queryStringParameters?.id;
if (!id) throw new Error("Missing id in query");
const result = await docClient.send(new GetCommand({
TableName: tableName,
Key: { id }
}));
body = result.Item || { message: "Item not found" };
break;
// ------------------- Update (PUT) -------------------
case "PUT":
body = JSON.parse(event.body);
if (!body.id) throw new Error("Missing id in body");
await docClient.send(new UpdateCommand({
TableName: tableName,
Key: { id: body.id },
UpdateExpression: "set message = :m",
ExpressionAttributeValues: { ":m": body.message }
}));
body = { message: "Item updated successfully" };
break;
// ------------------- Delete (DELETE) -------------------
case "DELETE":
const deleteId = event.queryStringParameters?.id;
if (!deleteId) throw new Error("Missing id in query");
await docClient.send(new DeleteCommand({
TableName: tableName,
Key: { id: deleteId }
}));
body = { message: "Item deleted successfully" };
break;
// ------------------- Unsupported -------------------
default:
throw new Error(`Unsupported method: ${event.httpMethod}`);
}
} catch (err) {
statusCode = 400;
body = { error: err.message };
}
// 回傳 API Gateway 格式的 Response
return {
statusCode,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body)
};
};
打開 API Gateway Console,點擊「建立 API」
選擇 REST API,填寫 API 名稱,例如 MessagesAPI
建立一個資源路徑 /messages
對 /messages
建立四個方法:
建立時要記得勾選「Lambda 代理整合」,這是 API Gateway 與 Lambda 函數之間的一種整合方式,讓 API Gateway 可以 完整地將 HTTP 請求資訊傳給 Lambda 函數,沒勾的話測試時會顯示錯誤呦!
最後我們點擊「部署 API」
在前幾天我們有介紹使用lambda中的「觸發」將API連接起來,今天我們用一樣方法連接後,再回到上面API的畫面做測試
1. POST 新增資料
{
"id": "1",
"message": "Hello DynamoDB"
}
2. GET 查詢資料
id = 1
3. PUT 更新資料
{
"id": "1",
"message": "Updated text"
}
4. DELETE 刪除資料
id = 1