Serverless Component 是 Serverless Framework 的,支持多个云资源编排和组织的场景化解决方案。html
Serverless Component 的目标是磨平不一样云服务平台之间差别,你能够将它看做是能够更轻松地构建应用程序的依赖模块。目前 Serverless Component 已经造成一个由社区贡献驱动的生态系统,你能够浏览和使用社区的全部组件,快速开发一款本身想要的应用。前端
基于 Serverless Component 架构,你能够将任何云服务打包成一个组件。这个组件将含有一份 serverless.yml
配置文件,而且经过简单地进行配置就可使用。本文以 @serverless/tencent-express 来举例。vue
若是咱们要使用它,只须要新建一个项目 express-demo
,而后修改 serverless.yml
配置以下:mysql
express: component: '@serverless/tencent-express' inputs: region: ap-shanghai
由于 serverless
框架部署到云的鉴权都是基于 dotenv 注入全局的变量来实现的,因此还得在根目录下新增 .env
文件,并配置对应的鉴权参数。ios
以后咱们就能够在 app.js
中轻松的编写基于 express
的接口服务了:git
const express = require('express') const app = express() app.get('/', function(req, res) { res.send('Hello Express') }) // 不要忘了导出,由于该组件会对它进行包装,输出成云函数 module.exports = app
这背后全部的流程逻辑都是组件内部实现的,包括:云函数的部署,API 网关的生成等。github
下面是一张简单的组件依赖图:web
经过此图能够清晰地查看组件带来的收益,借助社区现有的 @serverless/tencent-express 和 @serverless/tencent-website 组件,咱们就能够很快构建想要的全栈应用。sql
接下来将介绍如何借助 Serverless Component 快速开发全栈 Web 应用。vue-cli
在开始全部步骤前,需执行npm install -g serverless
命令,全局安装serverless cli
。
新建项目目录 fullstack-application-vue
,在该项目目录下新增 api
和 dashboard
目录。而后新增 serverless.yml
和 .env
配置文件,项目目录结构以下:
├── README.md // 项目说明文档 ├── api // Restful api 后端服务 ├── dashboard // 前端页面 ├── .env // 腾讯云相关鉴权参数:TENCENT_APP_ID,TENCENT_SECRET_ID,TENCENT_SECRET_KEY └── serverless.yml // serverless 文件
进入目录 api
,新增 app.js
文件,编写 express
服务代码,这里先新增一个路由 /
,并返回当前服务器时间:
const express = require('express') const cors = require('cors') const app = express() app.use(cors()) app.get('/', (req, res) => { res.send(JSON.stringfy({ message: `Server time: ${new Date().toString()}` })) }) module.exports = app
本案例使用的是 Vue.js
+ Parcel
的前端模板,固然你可使用任何前端项目脚手架,好比 Vue.js 官方推荐的 Vue CLI 生成的项目。进入 dashboard
目录,静态资源你能够直接复制我准备好的 项目模板,编写入口文件 src/index.js
:
// 这里初始是没有 env.js 模块的,第一次部署后会自动生成 require('../env') const Vue = require('vue') module.exports = new Vue({ el: '#root', data: { message: 'Click me!', isVisible: true, }, methods: { async queryServer() { const response = await fetch(window.env.apiUrl) const result = await response.json() this.message = result.message }, }, })
先后端代码都准备好了,如今咱们还须要简单配置下 serverless.yml
文件了:
name: fullstack-application-vue frontend: component: '@serverless/tencent-website' # inputs 为 @serverless/tencent-website 组件的输入 # 具体配置说明参考:https://github.com/serverless-components/tencent-website/blob/master/docs/configure.md inputs: code: src: dist root: frontend hook: npm run build env: # 下面的 API服务部署后,获取对应的 api 请求路径 apiUrl: ${api.url} api: component: '@serverless/tencent-express' # inputs 为 @serverless/tencent-express 组件的输入 # 具体配置说明参考:https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md inputs: code: ./api functionName: fullstack-vue-api apigatewayConf: protocol: https
简单的介绍下配置:首先,该文件定义了frontend
和api
两个模块,分别经过component
属性指定依赖的 Serverless Component。对于一个标准的 Serverless Component,都会接受一个inputs
属性参数,而后组件会根据inputs
的配置进行处理和部署,具体有关配置的参数说明,请参考相关组件的官方配置说明。
以上全部的步骤都完成后,接下来就是第一次部署了。
为何不是直接联调开发呢?由于后端服务是云函数,可是到目前为止,全部代码都是在本地编写,前端页面接口请求连接还不存在。因此须要先将云函数部署到云端,才能进行先后端调试。这个也是本人目前遇到的痛点,由于每次修改后端服务后,都须要从新部署,而后进行前端开发调试。若是你有更好的建议,欢迎评论指教~
部署时,只须要运行 serverless
命令就行,固然若是你须要查看部署中的 DEBUG
信息,还须要加上 --debug
参数,以下:
$ serverless # or $ serverless --debug
而后终端会 balabalabala~
, 输出一大堆 DEBUG
信息,最后只须要看到绿色的 done
就好了:
这样一个基于 Serverless Component 的全栈应用就开发好了。赶忙点击你部署好的连接体验一下吧~
既然是全栈,怎么少得了数据库的读写呢?接下来介绍如何添加数据库的读写操做。
想要操做数据库,必须先拥有一台数据库实例,腾讯云 MySQL 云数据库 如今也很便宜,能够购买一个最基本按量计费 1 核 1G 内存
的 1 小时收费不到 4 毛钱
,是否是很是划算。购买好以后初始化配置,而后新增一个 serverless
数据库,同时新增一张 users
表:
CREATE TABLE if not exists `test` ( `name` varchar (32) NOT NULL ,`email` varchar (64) NOT NULL ,`site` varchar (128) NOT NULL ) ENGINE = innodb DEFAULT CHARACTER SET = "utf8mb4" COLLATE = "utf8mb4_general_ci"
首先修改前端入口文件 frontend/src/index.js
新增相关函数操做:
require('../env') const Vue = require('vue') const axios = require('axios') module.exports = new Vue({ el: '#root', data: { // ... form: { name: '', email: '', site: '', }, userList: [], }, methods: { // ... // 获取用户列表 async getUsers() { const res = await axios.get(window.env.apiUrl + 'users') this.userList = (res.data && res.data.data) || [] }, // 新增一个用户 async addUser() { const data = this.form const res = await axios.post(window.env.apiUrl + 'users', data) console.log(res) if (res.data) { this.getUsers() } }, }, mounted() { // 视图挂在后,获取用户列表 this.getUsers() }, })
固然你还须要修改视图模板文件 frontend/index.html
,在页面模板中新增用户列表和用户表单:
<!-- user form --> <section class="user-form" action="#"> <div class="form-item"> <label for="name"> Name: </label> <input name="name" v-model="form.name" type="text" /><br /> </div> <div class="form-item"> <label for="email"> Email: </label> <input name="email" v-model="form.email" type="email" /><br /> </div> <div class="form-item"> <label for="site"> Site: </label> <input name="site" v-model="form.site" type="text" /><br /> </div> <button @click="addUser">Submit</button> </section> <!-- user list --> <section class="user-list"> <ul v-if="userList.length > 0"> <li v-for="item in userList" :key="item.id"> <p> <b>Name: {{ item.name }}</b> <b>Email: {{ item.email }}</b> <b>Site: {{ item.site }}</b> </p> </li> </ul> <span v-else>No Data</span> </section>
注意:若是还不熟悉 Vue.js 语法,请移至 官方文档,固然若是你想快速上手 Vue.js 开发,也能够阅读这份 Vue 从入门到精通 教程。
这里使用 .env
来进行数据库链接参数配置,在 api
目录下新增 .env
文件,将以前的数据库配置填入文件中,参考 api/.env.example
文件。而后添加并安装 dotenv
依赖,同时添加 mysql2
模块进行数据库操做,body-parser
模块进行 POST
请求时的 body
解析。
以后新增后端 api,进行数据库读写,修改后的 api/app.js
代码以下:
'use strict' require('dotenv').config() const express = require('express') const cors = require('cors') const mysql = require('mysql2') const bodyParser = require('body-parser') // init mysql connection function initMysqlPool() { const { DB_HOST, DB_PORT, DB_DATABASE, DB_USER, DB_PASSWORD } = process.env const promisePool = mysql .createPool({ host: DB_HOST, user: DB_USER, port: DB_PORT, password: DB_PASSWORD, database: DB_DATABASE, connectionLimit: 1, }) .promise() return promisePool } const app = express() app.use(bodyParser.json()) app.use(cors()) if (!app.promisePool) { app.promisePool = initMysqlPool() } app.get('/', (req, res) => { res.send(JSON.stringify({ message: `Server time: ${new Date().toString()}` })) }) // get user list app.get('/users', async (req, res) => { const [data] = await app.promisePool.query('select * from users') res.send( JSON.stringify({ data: data, }) ) }) // add new user app.post('/users', async (req, res) => { let result = '' try { const { name, email, site } = req.body const [res] = await app.promisePool.query('INSERT into users SET ?', { name: name, email: email, site: site, }) result = { data: res && res.insertId, message: 'Insert Success', } } catch (e) { result = { data: e, message: 'Insert Fail', } } res.send(JSON.stringify(result)) }) module.exports = app
这里数据库访问须要经过腾讯云私有网络,因此还须要为云函数配置私有网络(VPC),同时还须要配置可以操做数据库的角色(关于角色配置,能够直接到 角色管理页面),这里我新建了一个 QCS_SCFFull
的角色,能够用来访问数据库。而后修改 serverless.yml
中的配置:
# ... api: component: '@serverless/tencent-express' # more configuration for @serverless/tencent-website, # refer to: https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md inputs: code: ./api functionName: fullstack-vue-api role: QCS_SCFFull # 此角色必须具有访问数据库权限 functionConf: # 这个是用来访问新建立数据库的私有网络,能够在你的数据库实例管理页面查看 vpcConfig: vpcId: vpc-6n5x55kb subnetId: subnet-4cvr91js apigatewayConf: protocol: https
最后从新部署一下就好了。
以上基于腾讯云 Serverless Framework 来实现:
固然全栈方案,并无这么简单,这里只是简单介绍,如何使用 Serverless Component,快速实现一个全栈应用。若是要应用到实际的业务场景,咱们还需考虑更多的问题,期待你们去探索和发现!
传送门:
- GitHub: github.com/serverless
- 官网:serverless.com
欢迎访问:Serverless 中文网,您能够在 最佳实践 里体验更多关于 Serverless 应用的开发!
推荐阅读: 《Serverless 架构:从原理、设计到项目实战》