上一篇談到Lambda無法透過Http的方式直接讓外部呼叫,可是如果我們有這個需求時,那怎麼處理呢?這個時候,我們可以透過API Gateway的方式來處理。
API Gateway簡單得說,就是把一個網址放出來讓使用者可以呼叫,而呼叫後要做什麼,就是另外設定;雖說如此,目前API Gateway只支援下列四種設定:
而本篇主要介紹的,就是Lambda Function。
API Gateway的費用與免費額度
API Gateway主要是放出網址讓其他人呼叫,所以計費的部份就只有二個部份,一個是呼叫次數,一個是流量大小,除此之外,API Gateway也提供快取功能,不過當然是要額外收費的,所以這邊也不討論;而整個收費方式可參考官網,截圖如下:
至於我們最關心的免費額度,則是:
Amazon API Gateway 免費方案包含最多 12 個月每月 100 萬個 API 呼叫。
可能有讀者會現到了,AWS的免費方案只有針對呼叫的部份,不過我們在使用API Gateway的話,不可能不會產生流量,換句話說,只要使用API Gateway,即使在一年免費的額度中,還是會有費用產生,請注意。
API Gateway結合Lambda
建立Lambda Function
明明知道使用API Gateway會有費用產生,但若我們需要一個網址可以呼叫Lambda的話,還是得借助API Gateway的力量,這是最快的方法了。所以我們下方來介紹如何透過API Gateway來呼叫Lambda程式,不過在說明API Gateway時,必須先建立一個Lambda程式,所以我們先到Lambda去建立一個Function:
-
選擇Blank Function如下:
-
跳過下一步,什麼都不要選:
-
這裡建立一個AddTest的Function name:
而程式碼如下,主要是將傳入的二個參數相加後回傳:
exports.handler = (event, context, callback) => {
const bodyData = JSON.parse(event.body);
let sum=parseInt(bodyData.p1,10)+parseInt(bodyData.p2,10);
callback(null,{
statusCode: 200,
headers: {'Content-Type': 'application/json',},
body: JSON.stringify({'sum':sum,}),
});
};
-
選擇好「Lambda function handler and role」後,即可建立:
看到上圖即代表建立完成,而建立完成後,我們就要接著來建立API Gateway了。
建立API Gateway
首先先從AWS的網頁中找到「API Gateway」後進入。
第一次建立時,它會出現這樣的畫面:
這個說明的意思是:API Gateay有支援的一種叫Swagger格式的檔案,建議我們透過這種Swagger的方式來建立API Gateway;不過這邊我們先跳過,用最簡單的方式來建立API Gateway,如下圖:
建立完後可以看到這樣的畫面:
在這裡我們來解釋幾個在API Gateway中的專有名稱:
-
API:我們剛剛建立的東西就叫做API,在API Gateway中,API等同「專案」的意思,每個API之間不會互相影響。
-
Resource:API的基本內容,Resource可以想像成資料夾的概念,每一個API都會有一個Root的Resource,而Resource下可以繼續生成Resource,就如同Linux中,有一個基本的根目錄,而資料夾下可以生成資料夾。
-
Method:只存在於Resource底下,可以設定GET、POST、PUT、DELETE⋯⋯等HTTP Request的Method,Resource底下如果沒有設定Method,則這個Resource無法讓外部呼叫。
-
Stage:當我們處理好一個API的Resource與Method時,我們必須要把它佈署到Stage,這樣子,外部的網址才有辦法呼叫;也就是說,每次我們修改了API內的任何設定時,都要經過Stage的階段,這樣子外部的呼叫才會是最新的。另外,一個API可以有多個Stage,這種做法可以幫助我們進行分段的設計,例如:Develop stage與Product stage。
目前需要認識的這幾個API用的專有名詞,尤其是Resource、Method、Stage,這三種尤其重要,因為我們下方會用到,我們可以一邊看下去,一邊加深印象。
建立Resource
首先我們在左邊的Menu中,選擇Resource:
接下來我們在Action的按鈕中,可以找到「Create Resource」的功能,我們來建立一個像/math/add這樣的Resource:
選擇「Create Resource」後,在視窗的右邊會有一些資料需要填,我們首先先建立math的Resource。
再建立一個add的Resource的/math下面,如下圖:
建立好Resource後,再來就要建立Method了;先指定/add後,再到Action中選擇「Create Method」,我們來建立一個POST的Method:
建立後接下來的設定,就是當Request進入後,API Gateway會作什麼;在這裡,我們要做的當然是讓它去觸發Lambda,如下圖:
這邊有一個重點是:
Use Lambda Proxy integration的選項要勾選。
設定完後儲存即可;這樣我們就建立好一個API了,接下來就是把它佈署到Stage去,透過Action按鈕中的「Deploy API」,即可以佈署到Stage,參考下圖:
接下來我們選擇建立一個新的Stage,如下圖:
最後選擇「Deploy」,畫面會切換到Stage的畫面,並告知可呼叫的URL如下:
還記得我們的Resource是/math/add嗎?這時我們就可以透過網址的方式來呼叫了,不過,還有印象我們設定的Method是POST嗎?而且,我們的參數要怎麼從API Gateway帶到後端的Lambda呢?這裡我們就來瞭解一下整個流程。
瞭解API Gateway與Lambda的溝通
API Gateway中的Lambda Proxy integration選項
還記得我們在建立Method時有勾選「Lambda Proxy integration」這個選項嗎?就是下圖紅框的部份。
選擇了這個選項後,API Gateway會將Request的body資料,轉傳給Lambda,不過因為Lambda端接受的必須為物件(Object),所以在一開始的Request中,就必須是JSONObject格式了,例如:
{"p1":5,"p2":3}
這樣的文字,而因為我們要傳入JSON的格式,所以建議在HTTP的Header中帶入
Content-Type:application/json
的格式,因為我們要客製化我們的HTTP Request,所以建議安裝類似POSTMan之類的套件,讓我們可以發出客製化的Request,下方的範例使用的是FireFox的套件RESTED。
Lambda中取得Request body中的內容
只要我們的設定沒有問題,就可以在Lambda中的程式取得Request中的body內容,我們可以到Lambda的畫面中先行確認API Gateway會帶入的內容,透過「Configure test event」的方式(如下圖),就可以看到API Gateway會帶入的內容。
在「Sample event template」中選擇「API Gateway AWS Proxy」,就可以看到API Gateway會傳入的Lambda的範本。
在這裡可以透過修改body的參數來進行程式的測試,不過我們這邊先跳過,有興趣的讀者可以自行修改內容後,選擇「Save and test」進行測試。
而這整串JSON,最後都會變成我們的程式參數的event,所以我們在程式中就可以透過event.body的方式來取得Request中帶入的body內容。
Lambda回傳API Gateway
Lambda處理完資料後,必須將資料回傳給API Gateway,但是回傳是有一定格式的,格式必須為JSONObject並包含三個部份,分別是statusCode、headers、body,如果沒有這三個部份的話,在使用者與API Gateway的Reponse的這一端會收到502的Error,所以要注意一下。
測試
最後,我們就實際來測試吧,當我們發出一個預期的Request時,我們會得到下方的結果。
這樣,我們從使用者發出的Request,歷經API Gateway到Lambda,再由Lambda回到API Gateway再回到使用者,這一整串的流程,已經完成了。
留言列表