持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
背景
serverless很火,但是很多文章概念多实践少,也不适合个人开发者来玩耍。固然和硬件设备绑定,有完善生态的severless才有大的商业价值。但是个人想要试一下serverless总没有问题吧,结果看了一堆文章实现复杂,难以快速搭建落地。所以我准备自己搞一个serverless版本。
目标
- 云函数可以快速部署。
- 一个服务可以多个云函数。
- 接口式访问。
设计思路
一个云函数形成一个nodejs文件,服务端动态加载这些nodejs,访问文件对应的接口,就返回该云函数的运行结果。
工具库 与 实现
框架选择 koa
新建一个名字叫serverless的文件夹,然后进入文件夹后执行以下
代码语言:javascript复制npm init -y
npm i koa
库介绍
koa 与 koa-body
koa 是一个简单nodejs服务端框架,封装了nodejs的一些基础api,可以让你上手更快
koa-body 是一个基于koa,用于处理用户传入信息(Class: http.IncomingMessage)的库。IncomingMessage 又继承了 stream。而在koa中req是基于incomingMessage的再次封装。而一般业务逻辑中,我们不需要对流进行特别的处理,建议强烈建议使用 koa-body,来避免自己直接处理 IncomingMessage。
代码语言:javascript复制const Koa = require('koa');
const app = new Koa();
const koaBody = require('koa-body');
app.use(koaBody())
function test(ctx) {
console.log(ctx.request.body);
// => POST body
ctx.body = JSON.stringify(ctx.request.body);
}
app.use(test);
app.listen(3000);
glob 支持以某种规则读取目录下指定的文件
代码语言:javascript复制var glob = require("glob")
// options is optional
glob("**/*.js", options, function (er, files) {
// files is an array of filenames.
// If the `nonull` option is set, and nothing
// was found, then files is ["**/*.js"]
// er is an error object or null.
})
koa-router koa 的路由器中间件
实现热加载
目录结构
代码语言:javascript复制serverless
├─app.js
├─middleware
│ ├─get
│ │ └─test.js
│ └─post
├─package-lock.json
└─package.json
代码语言:javascript复制var Koa = require('koa');
var Router = require('koa-router');
var app = new Koa();
var router = new Router();
router.get('/', (ctx, next) => {
// ctx.router available
});
app
.use(router.routes())
.use(router.allowedMethods());
代码语言:javascript复制const path = require('path');
const Koa = require('koa');
const route = require("koa-route");
const koaBody = require("koa-body");
const glob = require('glob');
const app = new Koa();
app.use(
koaBody({
jsonLimit: '50mb',
})
);
// ----------------
setPostApi()
// 定时加载 接口文件
setInterval(() => {
console.log('first')
setPostApi()
}, 10000);
function json(ctx) {
return function (jn) {
ctx.body = JSON.stringify(jn)
}
}
function addJsonApi(fn) {
return async function (ctx) {
const { request, res } = ctx
request.cookies = {
'principal_dev': ctx.cookies.get('principal_dev')
}
res.json = json(ctx)
await fn(request, res)
}
}
function setPostApi() {
let fileList = glob.sync(path.join(__dirname, './middleware/post/*.js'));
fileList.map((file) => {
const { reg, fn } = require(file)
app.use(route.post(reg, addJsonApi(fn)));
});
fileList = glob.sync(path.join(__dirname, './middleware/get/*.js'));
fileList.map((file) => {
const { reg, fn } = require(file)
app.use(route.get(reg, addJsonApi(fn)));
});
}
app.listen(3000);
test.js 文件 内容
代码语言:javascript复制function aaaaa(req,res) {
res.json('ccccccc')
}
module.exports = {
reg: /test*/,
fn:aaaaa
}