因為越來越常需要教別人,所以整理成一篇說明文。
常常會被問到「不懂中間那一段是什麼」,但其實多半是在問 API Gateway,所以才取了這樣的標題。
這是一篇針對 API Gateway 初級~中級程度的解說文章。
我自己也還在持續學習中,如果有錯誤或容易造成誤解的表達,還請不吝指教。

我認為圖解起來大概會像這樣。
例如
https://API的網域/dev/index/必要的參數
這個路徑被呼叫時,

就會變成這樣。


階段是指像「正式環境」「開發環境」「測試環境」這類 API 的公開位置或執行環境的區隔。
在實際 URI 中,它位於網域後面的部分。(依照對應設定,也可以將階段隱藏起來)
https://example-api.amazonaws.com/dev/index
https://example-api.amazonaws.com/prd/index
透過這樣就能呼叫不同環境的 API。

資源是指 API 中公開的功能或端點的路徑單位。
/index → 取得首頁資料
/detail → 取得詳細資料
我認為這個概念接近 REST 的 ROA 中所說的 resource。在 API Gateway 上,則是作為表示路徑結構的設定項目來處理。

方法是指對資源要進行什麼操作(GET/POST/PUT/DELETE 等)。
我把它理解成 HTTP 方法。下面這篇文章非常不錯,也讓我學到很多。
方法有4 個構成要素,分別是方法請求、整合請求、整合回應、方法回應(在非代理整合的情況下,後面會說明)

我大致上是這樣理解的。

以下分別說明。


簡單來說,
定義要如何以 API Gateway 的形式接收來自用戶端的請求
就是它的職責。
也就是在用戶端的請求送到 API 的當下所進行的處理。
負責輸入驗證,以及驗證與授權的角色。
具體來說,會設定授權、是否需要 API 金鑰、URL 路徑/查詢字串/標頭等請求參數,以及視需要透過請求模型進行驗證。


簡單來說,
負責 API 與後端(這裡是 Lambda)之間的對應
就是它的工作。
會從整合類型中選擇要整合的是 Lambda,還是其他 AWS 服務(例如 Step Functions)等。
第二個作用是進行請求轉換等處理。
我個人最常見的是把輸入資料整理成 JSON 後再傳給 Lambda。
舉例來說,
當以 POST 接收商品資訊時,如果原本收到的請求是
/items?id=abc123&value=42
如果在非代理整合中,希望 Lambda 端能更方便處理,就可以在整合請求的對應樣板中,把查詢字串與路徑參數整理成 JSON 再傳過去。
{"id": "abc123", "value": 42}
就是會像這樣轉換。
另外,在整合請求中可以指定 Lambda 的別名。
上面的圖片中也有指定 dev 別名。

arn:aws:lambda:{region}:{account_id}:function:{function_name}:{alias_name}
像這樣在指定的函式後面加上 :{alias},就能將請求導向指定的別名。


負責接收後端的回應,並在 API 端進行加工。
等等設定都是在這一部分進行。
就我個人來說,這是最不容易直覺理解的概念。
在建立 API 時,基本上會做成像下面這樣的格式。
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"message\":\"hello\",\"userId\":123}"
}
但如果希望 Lambda 盡可能只回傳簡化後的回應,而把格式整理的部分交給 API Gateway,則可以像這樣:
{
"message": "hello",
"userId": 123
}
這樣來定義,並且不包含 statusCode 或 headers。這種情況下會使用的就是整合回應這個概念。
因此,當你要自行定義 statusCode 時,這部分其實就不是那麼必要;而如果希望在 Lambda 端組合出包含 statusCode 和 headers 的 HTTP 回應格式,使用代理整合可以讓設定更簡潔(後面會說明)。

這與其說是處理,不如說只是宣告。
簡單來說,
宣告可能回傳給用戶端的 HTTP 狀態碼、標頭與回應模型
就是這一部分。
具體而言,會宣告:
實際的值設定與轉換則是在整合回應端進行,而整合回應會把結果對應到對應的方法回應。
如果把前面提到的所有內容都在 API Gateway 端設定,會相當麻煩。
因此,為了省略這些設定,AWS 提供了代理整合。

我大致上是這樣理解的。相較於前面的非代理整合,對回應的處理幾乎都被簡化了,可以看得出來。
Lambda 代理整合的運作方式是:API Gateway 會把請求以事件物件的形式傳給 Lambda,再把 Lambda 的回應當作 HTTP 回應回傳給用戶端。
因此,可以減少像非代理整合那樣細部的對應設定。
不過因為幾乎是直接傳遞,所以 Lambda 端回應仍然必須符合一定規則的格式。
例如正常回應時,必須遵守以下格式。body 需要以字串指定,這點我覺得很有特色。
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"message\":\"hello\"}"
}
異常情況
{
"statusCode": 400,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"message\":\"bad request\"}"
}
也就是說,在代理整合中,雖然可以簡化非代理整合時進行的回應對應處理,但相對地,必須在 Lambda 端自行組裝回應格式。
詳細內容請參考文件。
以上就是 API Gateway → Lambda 的通訊流程。
API Gateway 看起來可能有點難懂,但如果把它拆成「接收請求的部分」「傳遞到後端的部分」「整理回應的部分」來看,應該會比較容易理解。
在與 Lambda 整合時,基本上多半會使用代理整合,讓 Lambda 端來控制流程;不過我也認為,對非代理整合有一定程度的理解同樣很重要。
感謝你讀到最後。