背景
在上一篇文章中,我谈到了offertalk的小程序整体设计于实现,相当于是小程序的前端开发,今天谈一下我是如何选择node并完成后端服务设计与实现的。
为啥选Node
后端语言千万种,为什么我选择了Node?基于一下几点考虑:
1.基于语言考虑,前后端同系语言JavaScript,能够避免各种乱七八糟的问题,例如:字符的解析等
2.考虑到小程序本就重网络IO,而非计算密集,Node即使是单线程,异步也能cover我的需要
3.微信小程序官方也提供NodeFaas云函数功能,可见Node用在小程序接口上是很实用的
有哪些框架可选
我们知道,用原生node可以非常容易的搭建一个服务,例如,下面的代码可以很容易的起一个监听3000端口的服务,但有什么缺点尼?
1.编写路由复杂
2.无中间件思想
3.数据解析方式复杂,无配套设施
const http = require('http');
http.createServer((req,res)=>{
req.on('data',(chunk)=>{
});
req.on('end',()=>{
res.end("success");
})
}).listen(3000, ()=>{
console.log('server is running on 3000');
})
我们再来看看Express,成熟的路由,成熟的模板引擎,成熟的代码MVC组织方式,这是可选的,使用use能很好的编写中间件来实现逻辑
var createError = require('http-errors');
var fs = require('fs');
var accessLogger = fs.createWriteStream('./logs/access.log', { flags: 'a' });
var errorLogger = fs.createWriteStream('./logs/error.log', {flags: 'a'});
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var bodyParser = require('body-parser')
var adminRouter = require('./routes/adminRouter');
var clientRouter = require('./routes/clientRouter');
var heartRouter = require('./routes/heart_ex_router');
const { render } = require('ejs');
var app = express();
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://10.1.1.129:3333');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials','true');
next();
};
app.use(allowCrossDomain);
app.use(bodyParser.json({limit:'50mb'}));
app.use(bodyParser.urlencoded({limit:'50mb',extended:true}));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(logger({ stream: accessLogger }));
app.use(function (err, req, res, next) {
var meta = '[' + new Date() + '] ' + req.url + '\n';
errorLogger.write(meta + err.stack + '\n');
next();
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', clientRouter);
app.use('/admin',adminRouter);
app.use('/heart',heartRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
if(err.status === 404){
res.render('404',{
title: 'Not Found'
});
return;
}
// render the error page
res.status(err.status || 500);
res.render('error');
});
Koa是express原班人马打造的更加轻量级的Node框架,特点在于洋葱模型,结合洋葱模型能够很好的处理业路由,业务逻辑等,也弥补了Express处理异步会乱七八糟的问题
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
Egg,基于koa以上封装的企业级Node应用框架,提供成熟的模块定义,代码模板方式,与数据库orm框架结合,能够很好的完成企业级应用的开发,这里不展开讲了,我用egg写过一些内部应用接口, 当然,offertalk小程序使用的是express作为服务端框架完成的接口的开发
对于框架我的疑惑是啥
上面说了这么多的框架,最近也有在看nest.js,越看越糊涂,因为自己有express,koa,egg的实际落地经验,深感为什么要搞这么多乱七八糟的框架尼,于是我在钉钉上找狼叔聊了聊,他是这么为我解答疑惑的
服务实现
在想法之初,我并没有想到会有一个web管理端来进行运营,因为开始我只是想做个demo,就只设计了小程序的接口,按照经典的mvc模型进行了模型的抽象与封装,并把一些定义好的工具函数进行了抽象封装
总结
项目我放在了腾讯云的1核1M的云服务器上,采用PM来维护服务进程,Nginx做域名映射,现在1k左右的人访问还是无妨,先这样用着吧