Author:心譚
From:【Serverless】設計實現SAM--無服務器應用模型
Des: 專一算法與 web 開發的技術博客javascript
sam全稱是:Serverless Application Model,也就是無服務器應用模型。html
它使用yaml語法來描述一個應用程序,服務商會對.yml
後綴的sam文件進行解析,並按照文件描述部署相關服務。前端
SAM的概念最初由AWS提出,用來描述程序所須要的Lambda function、Cloud DB等雲端資源。java
騰訊云云開發的擴展能力中,也使用SAM來描述擴展能力所須要的雲開發資源,包括雲函數、存儲、數據庫,甚至其餘的雲能力,例如短信發送。短信驗證碼登陸 自己就是擴展,用到了騰訊雲的短信能力。node
再發揮一下,sam能夠用來描述簡單的UI視圖,尤爲適合表單的應用場景,以下所示:git
由於sam是yaml語法文件,因此須要解析yaml語法,使用yaml.jsgithub
舉個例子,某個程序須要使用到雲函數,而且須要建立兩個數據表,SAM文件以下:web
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}'
整個流程總結:
${}
特殊字符串,替換變量