iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
Build on AWS

從零到雲端:AWS 開發之路系列 第 19

Day19 認識 DynamoDB(NoSQL 資料庫)並做簡單 CRUD

  • 分享至 

  • xImage
  •  

昨天我們已經學會如何透過 API Gateway + Lambda 做一個 Hello API,今天要進一步把「資料存下來」,不然每次 API 都只是回傳一個字串,沒辦法保留狀態。這時候我們需要「資料庫」(Database),而 AWS 提供的 NoSQL 服務就是 DynamoDB。

什麼是 DynamoDB?

DynamoDB 是 AWS 的全託管 NoSQL 資料庫,特點是:

  • 快速:毫秒級讀寫速度
  • 自動擴展:不用自己調整伺服器
  • Schema-less:不像 MySQL 需要固定欄位,資料結構比較彈性
  • 伺服器維護全由 AWS 處理:不用自己安裝 DB
    對我們來說,DynamoDB 很適合用來存放「使用者的留言、簡單設定、遊戲分數、記錄狀態」等資料。

Step 1:建立 DynamoDB 資料表
打開 DynamoDB Console,並點選「建立資料表」 (Create Table)。
設定:

  1. Table name: Messages
  2. Partition key: id(字串 String)
  • DynamoDB 的 必填主索引鍵。
  • 用來計算雜湊值,把資料平均分散到不同的分區,保證可擴展性與高效查詢。
  • 一定要在 CRUD 操作裡傳這個值,否則找不到資料。
  • 類型可以是 字串 (String) 或 數字 (Number),區分大小寫。

在我們的例子裡,Partition key 設成 id (String)。其他則保持預設,最後按建立完成,這樣我們就有一張可以存放留言的表格。
https://ithelp.ithome.com.tw/upload/images/20250928/20169251jncWLPHIH5.png

建立 Lambda 函數

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
https://ithelp.ithome.com.tw/upload/images/20250928/20169251zo0nWiA98U.png
環境變數是程式可以讀取的設定值,讓程式碼不需要硬編碼表名,也方便不同環境(開發/測試/正式)切換。
https://ithelp.ithome.com.tw/upload/images/20250928/20169251uotQoB6q1D.png

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:

  • Create(新增):透過 POST 方法,把使用者送來的訊息存進資料表。
  • Read(查詢):透過 GET 方法,根據 id 讀取指定的訊息。
  • Update(更新):透過 PUT 方法,更新指定 id 的訊息內容。
  • Delete(刪除):透過 DELETE 方法,刪除指定 id 的訊息。

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 REST API

打開 API Gateway Console,點擊「建立 API」
選擇 REST API,填寫 API 名稱,例如 MessagesAPI
建立一個資源路徑 /messages

/messages 建立四個方法:

  • GET
  • POST
  • PUT
  • DELETE

建立時要記得勾選「Lambda 代理整合」,這是 API Gateway 與 Lambda 函數之間的一種整合方式,讓 API Gateway 可以 完整地將 HTTP 請求資訊傳給 Lambda 函數,沒勾的話測試時會顯示錯誤呦!
最後我們點擊「部署 API」
https://ithelp.ithome.com.tw/upload/images/20250928/20169251mqrR52nvMz.png

使用 API 完成 CRUD

在前幾天我們有介紹使用lambda中的「觸發」將API連接起來,今天我們用一樣方法連接後,再回到上面API的畫面做測試
1. POST 新增資料

  • Method: POST
  • Request body:
{
  "id": "1",
  "message": "Hello DynamoDB"
}

https://ithelp.ithome.com.tw/upload/images/20250928/20169251yiamGXRneX.png

2. GET 查詢資料

  • Method: GET
  • Query string:
id = 1

https://ithelp.ithome.com.tw/upload/images/20250928/20169251VSyLzhlrzW.png

3. PUT 更新資料

  • Method: PUT
  • Request body:
{
  "id": "1",
  "message": "Updated text"
}

https://ithelp.ithome.com.tw/upload/images/20250928/20169251IUkt87EnCb.png

4. DELETE 刪除資料

  • Method: DELETE
  • Query string:
id = 1

https://ithelp.ithome.com.tw/upload/images/20250928/201692513OmyzXy79o.png


上一篇
Day18 認識 API Gateway(API 管理),建立一個REST API (2)
下一篇
Day20 設置前端讓「留言板 」活起來
系列文
從零到雲端:AWS 開發之路22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言