Day10 已經把後端邏輯放上 AWS 了,但總得有個通道打開讓我們可以呼叫到放在雲端的程式碼邏輯吧! 現在它就是一個「誰都呼叫不到」的函式喔~該怎麼解決呢? 於是這篇就要來介紹API Gateway啦! API Gateway就像是幫Lambda掛一塊門牌,讓瀏覽器可以用最熟悉的方式(一個網址 + HTTP Method)找到它。
一個 HTTP 請求,怎麼變成「呼叫一次 Lambda」?
概念很直接:在 API Gateway 上宣告一條規則,例如「POST /nutrition-plan 這個路徑跟方法,對應到某支 Lambda」。之後只要有請求打中這條規則,API Gateway 就會自動呼叫那支 Lambda 一次,並把回傳結果轉送回去。這個「把外部 HTTP 請求接到 Lambda 一次呼叫」的機制,正式名稱是 Lambda Proxy Integration。
先搞懂 event 到底是什麼
還記得Day10 有提到的 handler 函式嗎? 「當有事件進來時,就呼叫一次此函式,函式跑完回傳結果就結束」,當時提到的”事件”就是handler 函式其中一個參數 event
// handler 函式
export const handler = async (event, context) => {
// 這裡放後端邏輯
// event 裡面裝著「這次被叫醒的原因」,例如使用者送來的請求內容
return {
statusCode: 200,
body: JSON.stringify({ message: "算好了" }),
};
};
那其實”事件”event 大概長這樣:
{
"httpMethod": "POST",
"path": "/nutrition-plan",
"headers": { "content-type": "application/json" },
"body": "{\"height\":170,\"weight\":60}"
}
也就是說,前端送出的整個 HTTP 請求(方法、路徑、標頭、內文),會被 API Gateway 原封不動包成這個 JSON 物件,塞進 event 參數——這是 Lambda 唯一能知道「外面發生了什麼事」的管道。Lambda 裡要拿使用者填的表單資料,通常會寫 JSON.parse(event.body),讀的就是這個 body 欄位。
設定:template.yaml 的 Events
在 SAM 的 template.yaml 裡,只要在 Lambda 的 Events 屬性宣告一個 Api 類型的事件、指定 Path 跟 Method,SAM 部署時會自動連 API Gateway 都幫你建好,並直接把路由接到這支 Lambda:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Events:
NutritionPlan:
Type: Api
Properties:
Path: /nutrition-plan
Method: post
部署完,AWS 會給一個公開網址(像 https://xxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/nutrition-plan),前端的 fetch() 打這個網址,就能真正呼叫到 Lambda。
別忘了 CORS
有一件事一定會遇到:瀏覽器基於安全機制(同源政策),只有伺服器明確允許時,才准前端讀取跨網域的回應。所以除了路由設定,還要在 template.yaml 的 Globals.Api.Cors 開放允許的來源,並且在 Lambda 每個 return 裡加上 Access-Control-Allow-Origin。這不是額外的麻煩事,是前後端分開部署時一定會碰到的瀏覽器安全機制。
這支 Lambda 的觸發示意圖(AWS 自動畫的,可以看到接了 API Gateway 當觸發來源):
把 Day10 跟這篇兜起來,一次「使用者填表單 → 看到結果」的完整旅程長這樣:
②的 HTTP 請求(方法、路徑、標頭、內文)會被完整包成一個 JSON 物件,就是③的 event;Lambda 執行完後 return 的物件,會被 API Gateway 轉成⑤的 HTTP Response 送回瀏覽器。前面看起來很抽象的 Lambda 跟 API Gateway,串起來其實就是這麼直白的一條線。
下一篇要處理的,是這條線上還藏著一道關卡沒打通:Lambda 除了「被叫醒執行」,很多時候還要有「權限」去呼叫其他 AWS 服務(例如 Bedrock)——這道關卡就是 IAM。