《0到1实践系列》Node实现小程序后端开发

192 阅读3分钟

背景

在上一篇文章中,我谈到了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的实际落地经验,深感为什么要搞这么多乱七八糟的框架尼,于是我在钉钉上找狼叔聊了聊,他是这么为我解答疑惑的 image.png

服务实现

在想法之初,我并没有想到会有一个web管理端来进行运营,因为开始我只是想做个demo,就只设计了小程序的接口,按照经典的mvc模型进行了模型的抽象与封装,并把一些定义好的工具函数进行了抽象封装 image.png

总结

项目我放在了腾讯云的1核1M的云服务器上,采用PM来维护服务进程,Nginx做域名映射,现在1k左右的人访问还是无妨,先这样用着吧