在前幾篇文章中,我們完成了 Cognito + API Gateway + Lambda 的串接,讓前端能在驗證身分後呼叫後端。 今天開始,我們要將「資料」放進系統裡 —— 使用 Amazon DynamoDB 作為多人協作平台的儲存基礎。
DynamoDB 是 AWS 提供的 NoSQL 資料庫服務,它的特色是:
在 DynamoDB 裡,主要有三個需要理解的概念:
Table(資料表)
Trips
表來儲存行程資訊。Partition Key(分割鍵)
tripId
代表。Sort Key(排序鍵,可選)
在傳統的關聯式資料庫(RDB, Relational Database)裡,
「Table」是非常嚴謹的結構:
DynamoDB 也用「Table」這個詞,但意思不太一樣:
RDB Table | DynamoDB Table | |
---|---|---|
Schema | 固定欄位 | 動態欄位 (每筆資料可以不同) |
主鍵 | Primary Key (常配合 Foreign Key) | Partition Key (+ Sort Key) |
儲存單位 | Row (列) | Item (JSON-like 文件) |
功能重點 | 關聯 & 查詢 | 高效查 Key & 擴展性 |
所以可以把 DynamoDB Table 理解成:
「一個裝著很多 JSON 文件的資料夾,只是這些文件都必須有個唯一的 Key。」
接下來我們會從這個角度,看看怎麼設計 Table 給專案使用。
前往 AWS Console → DynamoDB → Create table
Table name:
DemoTable
Partition key:userId
(String)
Sort key:itemId
(String)
其他設定用預設值即可(Free Tier 已經足夠)。
建立完成後,你就擁有了一個可以存放資料的 DynamoDB Table。
接著我們建立一個最簡單的 Lambda function,目標只是:
程式碼範例我會另外放在 GitHub repo,這裡先聚焦概念:
boto3
for Python)。put_item
可以新增一筆資料。get_item
可以根據 Key 把資料取出。# Lambda CRUD 範例
import boto3
import os
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb')
table_name = os.environ.get("TABLE_NAME", "TodoTable")
table = dynamodb.Table(table_name)
# Create
def create_todo(user_id, todo_id, content):
table.put_item(Item={
"userId": user_id,
"todoId": todo_id,
"content": content
})
# Read
def get_todos(user_id):
response = table.query(
KeyConditionExpression=Key("userId").eq(user_id)
)
return response.get("Items", [])
# Update
def update_todo(user_id, todo_id, new_content):
table.update_item(
Key={"userId": user_id, "todoId": todo_id},
UpdateExpression="SET content = :c",
ExpressionAttributeValues={":c": new_content}
)
# Delete
def delete_todo(user_id, todo_id):
table.delete_item(Key={"userId": user_id, "todoId": todo_id})
在實務專案中,Lambda 不是單獨運作的,通常會透過 API Gateway 接收前端請求,並用 Cognito 驗證使用者身份。這樣可以確保:
整個流程概念如下:
程式碼示範:
# Lambda + API Gateway 認證示範
import json
import boto3
import os
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ.get("TABLE_NAME", "TodoTable"))
def lambda_handler(event, context):
# Cognito 認證資訊會在 event['requestContext']['authorizer'] 內
user_id = event['requestContext']['authorizer']['claims']['sub']
http_method = event['httpMethod']
if http_method == "GET":
items = table.query(KeyConditionExpression=Key("userId").eq(user_id)).get("Items", [])
return {"statusCode": 200, "body": json.dumps(items)}
elif http_method == "POST":
body = json.loads(event['body'])
table.put_item(Item={"userId": user_id, "todoId": body["todoId"], "content": body["content"]})
return {"statusCode": 200, "body": json.dumps({"message": "Created"})}
# Update & Delete 可以依照前面 CRUD 範例實作
今天我們完成了:
下一篇,我們會繼續探索 如何設計資料表結構,並逐步帶入專案的實際需求。