設計實現SAM–無伺服器應用模型
- 2020 年 8 月 4 日
- 筆記
- NodeJs深入淺出
Author:心譚
From:【Serverless】設計實現SAM–無伺服器應用模型
Des: 專註演算法與 web 開發的技術部落格
什麼是SAM?
sam全稱是:Serverless Application Model,也就是無伺服器應用模型。
它使用yaml語法來描述一個應用程式,服務商會對.yml
後綴的sam文件進行解析,並按照文件描述部署相關服務。
應用場景
SAM的概念最初由AWS提出,用來描述程式所需要的Lambda function、Cloud DB等雲端資源。
騰訊云云開發的擴展能力中,也使用SAM來描述擴展能力所需要的雲開發資源,包括雲函數、存儲、資料庫,甚至其他的雲能力,例如簡訊發送。簡訊驗證碼登錄 本身就是擴展,用到了騰訊雲的簡訊能力。
再發揮一下,sam可以用來描述簡單的UI視圖,尤其適合表單的應用場景,如下所示:
實現簡易的SAM
定義SAM
因為sam是yaml語法文件,所以需要解析yaml語法,使用yaml.js
舉個例子,某個程式需要使用到雲函數,並且需要創建兩個數據表,SAM文件如下:
ApplicationName: 測試程式
# 雲函數資源
Function:
# 運行環境
Container: nodejs 8.9
# 超時時間(秒)
Timeout: 60
Corn:
# 雲資料庫資源
Database:
# 需要創建的數據集合
Collections:
-
CollectionName: 'ext-collection-a'
-
CollectionName: 'ext-collection-b'
數據校驗
由於前端輸入的數據不可信,後端需要對傳入的SAM進行校驗。
隨著依賴的資源欄位增加,單純使用 if-else
的邏輯判斷,會讓程式碼變得難以維護,可讀性非常差。
通常有2種數據校驗的思路:
- 藉助
joi.js
,在程式碼中增加校驗邏輯 - 使用
ajv.js
,分離Schema和程式碼邏輯
第2種思路耦合度更低,並且規則的改動和維護,不涉及程式碼改動,產品和運營同學也可以來維護規則。
按照schema的ajv語法,以前面的SAM文件為例,schema 的內容如下:
{
"type": "object",
"properties": {
"ApplicationName": {
"type": "string"
},
"Function": {
"type": "object",
"required": ["Container", "Timeout"],
"properties": {
"Container": {
"type": "string"
},
"Timeout": {
"type": "number"
},
"Corn": {
"type": ["string", "null"]
}
}
},
"Database": {
"type": "object",
"Collections": {
"type": "array",
"items": {
"properties": {
"CollectionName": {
"type": "string"
}
}
}
}
}
}
}
封裝ajv的驗證邏輯:
const Ajv = require('ajv')
/**
* 驗證obj是否符合 Schema 定義
* @param {object} obj
* @param {string} schemaJson
* @return {boolean}
*/
function validateSchema(obj, schemaFilePath) {
const schemaJson = require(schemaFilePath)
const ajv = new Ajv()
const validate = ajv.compile(schemaJson)
const valid = validate(obj)
if (!valid) {
console.log('>>> 錯誤欄位資訊:', validate.errors)
}
return valid
}
變數注入
有些時候,某些變數是動態的。例如,用戶資訊可能在運行過程中被注入到上下文,數據集合名稱需要前端用戶表單傳入。
舉個例子,前面創建的兩個數據集合的名稱由前端表單傳入,對應欄位是:collectionNameA
和collectionNameB
。
# 雲資料庫資源
Database:
# 需要創建的數據集合
Collections:
-
CollectionName: '${env.collectionNameA}'
-
CollectionName: '${env.collectionNameB}'
整個流程總結:
- 服務端解析預設的SAM配置
- 識別
${}
特殊字元串,替換變數 - 驗證是否符合Schema定義的規則
參考鏈接
- AWS Serverless Application Repository
- AWS 無伺服器應用程式模型 (SAM) 命令行介面介紹
- JSON Schema validation keywords
- AJV schema validation for nested object