前言

上一篇 基于 Serverless Component 的全栈解决方案 介绍 Serverless Component 是什么和如何使用 Serverless Component 开发一个全栈应用。但是目前社区还不够完善,当我们需要一个还没有的组件时,怎么办呢?

与其向官方提交 issue,说明需求,不如自己动手撸一个,岂不快哉~

Serverless Component 运行机制

在开始开发之前,我们先来了解下 Serverless Component 的运行机制:

每个 Serverless Component 实际上就是一个 npm 包,你可以通过 npm install 命令直接安装。当我们在一个依赖 Serverless Component 的应用中,执行命令 serverless --debug 部署时,它首先会读取 serverless.yml 文件中的 component 参数指定组件模块,它会像安装 npm 包一样,自动安装到本地,然后自动注入该组件模块,同时执行组件中的 default 函数(之后会讲到),从而完成部署流程。

开发步骤

一个完整组件的开发流程应该包括以下流程:

  1. 明确功能需求
  2. 定义组件配置:输入和输出参数
  3. 组件开发:default 函数、remove 函数(可选)
  4. 测试组件
  5. 发布 npm 包

接下来将按照以上步骤,一步一步实现腾讯云 CDN 组件。

1. 明确功能需求

腾讯云 CDN 控制台 已经提供了手动配置加速域名的功能,但是作为一名懒惰的程序员,「手动」 一直都是我尝试规避的问题。于是去看了看腾讯云文档,看看官方有没有提供相应便捷的方式。果不其然腾讯云 API 已经提供了相关接口,那么我们为什么不借助 API 实现一个能够帮助我们自动配置的 CDN 组件呢?

需求很明确:开发一个能够自动配置 CDN 加速域名的组件,帮助我们节省手动配置时间。

2. 定义组件配置

要实现 CDN 域名的添加,需要借助 2 个腾讯云 API 接口:新增加速域名HTTPS 配置。通过阅读这两份接口文档,总结出一份配置说明文件 config.md ,内容如下:

MyCDN:
component: '@serverless/tencent-cdn'
inputs:
host: abc.com
hostType: cos
origin: www.test.com
backupOrigin: www.test.com
serviceType: web
fullUrl: on
fwdHost: ww.test.com
cache:
- type: 0
rule: all
time: 1000
- type: 0
rule: all
time: 1000
cacheMode: simple
refer:
- type: 1
list:
- 'qq.baidu.com'
- '*.baidu.com'
accessIp:
type: 1
list:
- '1.2.3.4'
- '2.3.4.5'
https:
certId: 123
cert: 123
privateKey: 123
http2: off
httpsType: 2
forceSwitch: -2

其中 inputs 就是组件的输入参数,其实这些参数都是从接口文档中拷贝出来而已,实际开发时,需根据自己组件功能,定制化配置就好。

无服务框架的配置都是 yaml 文件,所以在定义组件配置时,需要将 API 的参数做好 yaml 规范映射。比如 yaml 文件中,符号 - 是用来定义数组的。如果对 yaml 语法还不太熟,可以参考这份 YAML 语言教程

组件输入定义好了,还需要定义输出内容,只需要大致的组织 API 请求返回结构就行,尽量简洁明了:

{
host: 'abc.com',
hostId: '123'
origin: 'www.test.com',
cname: 'www.test.com.cdn.dnsv1.com',
https: true
}

3. 组件开发

对于一个标准的 Serverless Component ,结构如下:

// serverless.js
const { Component } = require('@serverless/core')
class MyComponent extends Component {
/*
* Default (必须)
* - default 是用来执行、准备和更新你的组建的函数
* - 执行命令 `$ serverless` 会运行此函数
* - You can run this function by running the "$ serverless" command
*/
async default(inputs = {}) {
return {}
} /*
* Remove (可选)
* - 如果你的组件需要删除基础设施,推荐你添加他
* - 执行命令 `$ serverless remove` 会运行此函数
*/
async remove(inputs = {}) {
return {}
} /*
* Anything (可选)
* - 如果你想发布带有额外功能的组件,你可以将逻辑写在一个函数里,函数名可以自定义
* - 执行命令 `$ serverless anything` 会运行此函数
*/
async anything(inputs = {}) {
return {}
}
}
module.exports = MyComponent

了解了组件的结构,接下来,就开始开发吧~

3.1 初始化项目

创建项目目录 tencent-cdn,执行 npm init 初始化项目,根据命令指引,填写相关信息就行:

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields
and exactly what they do. Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file. Press ^C at any time to quit.
package name: (cdn-module) tencent-cdn
version: (1.0.0)
description: Tencent Cloud CDN Component
entry point: (index.js) serverless.js
test command:
git repository:
keywords: cdn,serverless,serverless-component,serverlesscomponent,tencent
author: yugasun
license: (ISC) MIT
About to write to /Users/yugasun/Desktop/Develop/serverless/cdn-module/package.json: {
"name": "tencent-cdn",
"version": "1.0.0",
"description": "Tencent Cloud CDN Component",
"main": "serverless.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"cdn",
"serverless",
"serverless-component",
"serverlesscomponent",
"tencent"
],
"author": "yugasun",
"license": "MIT"
} Is this OK? (yes)

然后新建 serverless.js 文件,复制上面的模板代码到 serverless.js 文件中。

3.2 编写 default 函数

default 函数代码,这里就不贴出来了,有点多 o(╯□╰)o。

主要思路就是,根据 inputs 输入参数,规范成接口请求参数,然后请求接口,执行配置就好。

对于腾讯云 API,所有的接口请求都需要鉴权,所以这里需要先实例化一个 Capi,如下:

import { Capi } from '@tencent-sdk/capi'
const capi = new Capi({
SecretId: this.context.credentials.tencent.SecretId,
SecretKey: this.context.credentials.tencent.SecretKey,
ServiceType: 'cdn',
})

注意:关于请求云 API 库 @tencent-sdk/capi 说明文档已经很全面了,当然你也可以在这里看到 源码.

它需要传入 SecretIdSecretKeyServiceType 三个参数,SecretIdSecretKey 可以通过 this.context.credentials.tencent 来获取,执行 serverless 命令在执行时,它会根据用户项目根目录配置的 .env 文件,自动注入到 this.context.credentials.tencent 上。ServiceType 是当前服务类型,这是腾讯云 API 定义的,针对不同业务配置相应参数就行。

注意:不同的云服务商挂到 this.context.credentials 上的属性也是不一样,比如这里腾讯云是 tencent,AWS 是 aws,目前支持的所有云服务商的属性配置源码,在这里可以找到,@serverless/cli

然后请求 新增加速域名 接口:

// cdnInputs 就是我们组装好的请求参数
await AddCdnHost(capi, cdnInputs)

这里有个重点:请求 新增加速域名 接口成功返回后,CDN 并不会立即部署成功,这个是需要时间的,所以我们执行后,需要轮训当前新增域名的状态,当为部署成功时,我们才能进行之后的逻辑。

3.3 组件状态保存

Serverless Component 在执行 default 函数时,它会产生一些状态,比如新增 CDN 域名成功后,会产生一个 hostId,我们可以保存在 this.state 对象中,通过执行 this.save() 函数,它会将 this.state 保存到项目根目录的 .serverless 文件夹中一个名为 Template.MyCDN.jsonMyCDN 是我定义的当前 Serverless 应用的名称)文件中,方便之后在做组件建删除时使用。

3.4 编写 remove 函数

Serverless Component 删除的逻辑,就是再 serverless remove 命令时,它会读取 default 函数执行保存到 .serverless 中的状态文件,并注入到 this.state 上 , 然后我们可以根据 state 中的值进行移除,比如我这里会用到 host, 因为 删除加速域名接口 需要传递 host 参数。

3.5 完善说明文档

开源项目的 README 一定要写的清晰明了,方便开发者顺利的使用和开发。

4. 测试组件

到这里我们组件的基本开发完成了,在发布之前,还得进行本地测试,Serverless Framework 提供了一个很好地本地调试方法,就是应用的 serverless.ymlcomponent 可以指定本地项目路径,比如在 tencent-cdn 目录下,创建 test 文件夹,然后新增 serverless.yml 配置如下:

MyCDN:
component: ../
inputs:
host: abc.com
...

这里的 ../ 就是相对路径,因为 tencent-cdn 组件的 serverless.js 文件在 tencent-cdn 根目录下,之后我们就可以进入 test 目录,执行部署和移除操作,来测试我们的组件了。

注意:虽然一个 Serverless Component 是一个 npm 模块,我们可以通过 package.json 中的 main 属性指定项目中任意的文件入口,但是如果没有 serverless.js 文件,serverless 命令是没法通过 component 指定的本地路径调试的。

5. 发布 npm 包

发布 npm 包,首先需要你拥有一个 npm 账号,请先前往 npm官网 注册,然后本地执行 npm login 登录你的账号。

经过测试没问题,就可以执行 npm publish 就可以发布到 npm 仓库了。

源码

最终实现源码:@serverless/tencent-cdn

组件引用

每个组件实例,都会有个 load 方法,我们可以通过此方法来加载其他组件,如下:

const cdnComp = await this.load('@serverless/tencent-cdn', 'cdnComp');

借助此功能,我们可以实现很多高阶组件,比如 @serverless/tencent-website 就是一个很好地案例。

至于如何组合你的组件,实现自己的需求,就靠你自己去天马行空了,是不是已经跃跃欲试了?快来社区贡献你的一份力量吧~

组件开发模板

以上基于腾讯云 Serverless Framework 来实现,这里还有个 Serverless Component 开发模板,可以帮你快速开发一个 Serverless Component:模板链接,英文好的话可以查看这两篇内容《How to write your first Serverless Component》《Building Serverless Components》

传送门:

欢迎访问:Serverless 中文网,您可以在 最佳实践 里体验更多关于 Serverless 应用的开发!

如何开发自己的第一个 Serverless Component的更多相关文章

  1. Serverless Component 介绍和使用指南

    Serverless Component 是什么,我怎样使用它? Serverless Components 的目标是什么? 我们希望通过 Serverless Components 让广大开发者更加 ...

  2. 基于 Serverless Component 全栈解决方案

    什么是 Serverless Component Serverless Component 是 Serverless Framework 的,支持多个云资源编排和组织的场景化解决方案. Serverl ...

  3. 基于 Serverless Component 全栈解决方案 Ⅱ

    虽然之前的文章 基于 Serverless Component 的全栈解决方案 介绍了如何借助 Serverless Component 快速搭建 Restful API 后端服务 和 Vue.js ...

  4. Web程序员开发App系列 - 开发我的第一个App,源码下载

    Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...

  5. ArcGIS API for JavaScript开发环境搭建及第一个实例demo

    原文:ArcGIS API for JavaScript开发环境搭建及第一个实例demo ESRI公司截止到目前已经发布了最新的ArcGIS Server for JavaScript API v3. ...

  6. [android开发IDE]adt-bundle-windows-x86的一个bug:无法解析.rs文件--------rs_core.rsh file not found

    google的android自带的apps写的是相当牛逼的,将其导入到eclipse中方便我们学习扩展.可惜关于导入的资料太少了,尤其是4.1之后的gallery和camera合二为一了.之前导4.0 ...

  7. Android Wear 开发入门——怎样创建一个手机与可穿戴设备关联的通知(Notification)

    创建通知 为了创建在手机与可穿戴设备中都能展现的通知,能够使用 NotificationCompat.Builder.通过该类创建的通知,系统会处理该通知是否展如今手机或者穿戴设备中. 导入必要的类库 ...

  8. 开发你的第一个BLE应用程序—Blinky

    本文将和大家一起编写我们的第一个BLE应用程序:Blinky(闪灯程序),哪怕你之前没有任何BLE开发经验,也不用担心,只要跟着文中所述步骤,你就可以一步步搭建自己的第一个BLE应用程序.通过这个Bl ...

  9. 【转】Esp8266学习之旅① 搭建开发环境,开始一个“hellow world”串口打印。

    @2019-02-28 [小记] Esp8266学习之旅① 搭建开发环境,开始一个“hellow world”串口打印.

随机推荐

  1. 【MySQL 原理分析】之 Trace 分析 order by 的索引原理

    一.背景 昨天早上,交流群有一位同学提出了一个问题.看下图: 我不是大佬,而且当时我自己的想法也只是猜测,所以并没有回复那位同学,只是接下来自己做了一个测试验证一下. 他只简单了说了一句话,就是同样的 ...

  2. Airtest自动化测试工具介绍

    官方网站:http://airtest.netease.com/ Airtest IDE: 跨平台的UI自动化测试编辑器,适用于游戏和App,详细参见官网文档:http://airtest.netea ...

  3. Http POST 提交 415错误 Unsupported Media Type 解决方案

    1 问题 在调用webapi post 提交时出现 415 Unsupported Media Type 错误 前端代码如下: $.post("/api/student/poststuden ...

  4. Codeforces_821

    A.直接判断每一个数. #include<bits/stdc++.h> using namespace std; ][]; int main() { ios::sync_with_stdi ...

  5. 《古剑奇谭3》千秋戏辅助工具(前端React制作)

    前言 一直身在武汉,基于众所周知的疫情原因,这个春节只能宅着. 不过其实这个春节是这些年来过得最爽的一个了. 没有鞭炮,不用四处跑,安安心心呆在家里玩玩游戏看看书写写代码,其实日子过得还是挺悠闲的. ...

  6. Python原来这么好学-1.2节: 在Linux中安装python

    这是一本教同学们彻底学通Python的高质量学习教程,认真地学习每一章节的内容,每天只需学好一节,帮助你成为一名卓越的Python程序员: 本教程面向的是零编程基础的同学,非科班人士,以及有一定编程水 ...

  7. tar命令详解及使用实例

    tar命令 [root@linux ~]# tar [-cxtzjvfpPN] 文件与目录 …. 参数: -c :创建压缩文件 -x :解开压缩文件 -t :查看tar包里面的文件! 上面3个参数只能 ...

  8. Nginx之美多商城前台部署

    这里我们采用动静分离的方式来部署美多商城项目. 动态请求:采用uwsgi与Django进行通信处理动态业务. 静态请求:采用Ngins通过socket与uwsgi进行通信处理静态业务. 第一步:实现u ...

  9. 10-SpringMVC04

    FreeMarker 1.入门案例 1. 导包:freemarker.jar 2. 需要创建模板文件的路径:src/main/resources/template 3. 创建一个模板对象:hello. ...

  10. javascript Date对象 js全部的 时间属性 和 方法

    Date() 返回当日的日期和时间. getTime() 返回 1970 年 1 月 1 日至今的毫秒数. getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31).天 getDa ...