深入 Serverless

yu.chiang
6 min readAug 5, 2016

--

初探 Serverless 中做了大致的介紹以及如何從安裝到部署的流程,但使用 serverless 部署完 Lambda function 後到底該從哪裡開始?因為要使用 serverless 同時間也會牽扯到很多東西,除了基本的 Lambda、API Gateway,還有 API 權限控制的 IAM role、記錄 log 的 CloudWatch … 等等。這篇會從檔案結構跟相關設定開始講起,之後實際跑一次開發流程,最後介紹如何觀看 log。

serverless v0.5.5

檔案結構

使用 serverless 建立 project 後,可看到它會建立以下結構的資料夾與檔案。

建立了這麼多東西,其實不會所有都會去動到,主要會圍繞在所建立的 function 下的兩個檔案,handler.js (Lambda) 與 s-function.json (API Gateway)。

s-function.json

s-function.json 裡的設定在部署時會對應到 API Gateway 中。裡面的設定主要可分成 3 個部份: Function、Event、Endpoint。

雖然這一大堆設定看起來好像很可怕,不過基本上只要專注在 Endpoint 區塊內的設定就好,詳細的設定方法會在後面實際演練時介紹。

handler.js

這是 handler.js 的原貌,在 初探 Serverless 的最後測試所跑出來的畫面就是執行這個 function 來的,以下就這些內容來做介紹。

handler

在 handler.js 中 module.exports.handler,就是對應到 s-function 內 handler 屬性的值 handler.handler,名稱可以任意更改,只要有對應到 s-function.json 就好。

event

event 底下帶有 request 進來的資料,資料的格式在 s-function.json 內的 requestTemplates 設定。假設我的 function method 是 POST,我在呼叫這個 function 時給了猜數 { foo: bar },則 event.foo === bar。

context

用於在要終止 function 時呼叫,context 下有三種函式來處理 function 執行後的結果,分別是 succeed、fail、done。

  • succeed(Object result):在 function 執行成功後使用。
  • fail(Error error):處理 function 執行失敗後的使用。
  • done(Error error, Object result):執行結束後使用,可以帶同時帶入成功或錯誤的值。

在函式中帶入的物件會 response 回用戶端,response 的格式在 s-function.json 內的 responseTemplates 中設定。

cb

大概只有建 function 時用來測試會用到。

s-templates.json

這個檔案在初始建立 function 的時候並不會有,需要自己來建立,通常跟 s-function.json 放在同一層。裡面用來存放 request 與 response 的資料格式,範例如下:

其中 apiRequestTemplate 與 apiResponseTemplate 為自定義名稱。application/json 內的參數就是資料的格式,其中物件 key 值代表參數要使用的名稱,value 代表參數的型態,詳細的型態內容可參考 API Gateway API Request and Response Payload-Mapping Template Reference

較常用的是上述範例中的 httpMethod 與 body。其中 $context.httpMethod 是接收 request 來的 header 參數中的 method,用來判斷 request 的行為 (GET、POST …)。$input.json(‘$’) 則表示資料為 json 的型態,參數在 request 與 response 中皆可使用。

設定好之後回到 s-function.json,把在 s-templates.json 中的設定寫進去,這樣就完成了資料格式與型態的設定。

也可將 s-templates.json 放在 function 的上一層,如下圖。若父層之 s-templates.json 內之宣告名稱與子層宣告的名稱相同,則子層會繼承父層所設定之參數。

例如父層的 s-templates.json 有設定 apiRequestTemplate 中有 httpMethod,則子層中 s-templates.json 只要參數有命名叫 apiRequestTemplate 的都會預設帶有 httpMethod。

實際演練

在上面講了那麼多的設定,但剛接觸時實際動手也容易不知道該如何下手。所以這裡試想一個簡單的情境,綜合以上的設定來跑一次操作流程,會比較能對 serverless 有一些感受。

假設我今天想在我的 GET request 後直接帶一個數字到 server,希望 server 幫我把這個數字加上 10 然後回傳給我。

example:

request:/add10/2response:{ number: 12 }

這樣會需要先到 s-function.json 中將 request 的 path 改成 url 帶參數的方式。

之後到 s-template.json 中來設定要接收與回傳的資料格式,記得寫回 s-function.json。

最後回到程式的主體,先從 event 中把 url 的 number 值抓出來並加上 10,再將結果回傳即可。

Log

如果對 serverless 有大概的認識,也開始進入到寫程式後,那最常碰到的問題大概就是要如何看 log 來解 bug 了。通常在寫一般 nodejs 時,是使用 console.log 來將資料印在 terminal 上,而寫 serverless 也是使用 console.log,只是你要印的值會存 AWS CloudWatch 中的 Log 中。下圖中 Log Groups 所列的就是所部署上去的 Lambda function,若你在程式中有加入 console.log 來印出某些值,在你執行到 function 時都會把 log 存在其中。

參考:

淺析 serverless 架構與實作

AWS Lambda 開發人員指南

Serverless document

Serverless Starter

--

--