zoukankan      html  css  js  c++  java
  • 设计实现SAM--无服务器应用模型

    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
    }
    

    变量注入

    有些时候,某些变量是动态的。例如,用户信息可能在运行过程中被注入到上下文,数据集合名称需要前端用户表单传入。

    举个例子,前面创建的两个数据集合的名称由前端表单传入,对应字段是:collectionNameAcollectionNameB

    # 云数据库资源
    Database:
        # 需要创建的数据集合
        Collections: 
            -
                CollectionName: '${env.collectionNameA}'
            -
                CollectionName: '${env.collectionNameB}'
    

    整个流程总结:

    • 服务端解析预设的SAM配置
    • 识别${}特殊字符串,替换变量
    • 验证是否符合Schema定义的规则

    参考链接

  • 相关阅读:
    第三章:WebDriver 通过 XPath来 定位 table 表格
    第三章:对话框的 alertconfirmprompt 的处理
    第三章:iframe 的处理
    第三章:鼠标悬停 Actions
    第三章:文件上传
    弱网测试:Network-Emulator-Toolkit 工具中的一些词汇
    linux 下查看机器是cpu是几核的
    linux系统硬件配置
    Linux内核分析课程总结
    《Linux内核设计与实现》课本第四章自学笔记——20135203齐岳
  • 原文地址:https://www.cnblogs.com/geyouneihan/p/13435209.html
Copyright © 2011-2022 走看看