Express4 + MongoDB 服务端搭建

简介

可以作为使用Nodejs进行前后端分离开发时,后端服务器搭建基本过程的参考。习惯阅读代码的可以直接跳到文末进行阅读

前序条件、基本环境

    需要 nodeJS 环境、MongoDB环境
    执行 npm install -g express-generator@4 安装express4
    执行 npm install -g supervisor 安装一个工具,用于自动重启,并应用代码(可选)

生成基本框架

在工程目录上一级执行以下命令,用于自动生成工程目录以及相关的基本文件

express -e home

 因为是前后端分离,所以生成的 view 文件夹都没用了,可以移除(public目录下提供静态文件服务的子目录也可以选择性删除),但是移除后需要修改 app.js 中关于 view 的处理,即删除 view 配置、使用部分的代码。否则会报错,文末会给出相关代码。

修改 package.json ,修改启动命令为 supervisor ./bin/www 如果安装了 supervisor 的话可以使用,将 "mongoose": "*" 添加到 dependencies 中。命令行进入工程目录,执行下列命令安装依赖包:

npm install

 安装完成后,在工程目录下执行下列命令启动程序

npm start

 现在访问在浏览器 http://127.0.0.1:3000/stylesheets/style.css 可以得到正确文件内容,到这里,基本框架整完了。(因为删除了view,无法访问页面,如果连这个 css 文件也一并删除了的话,报错是正常的)

配置返回 JSON

这里使用 json 作为返回给前端的数据格式。其实就是在路由规则的函数中调用 res.json() 方法,将需要作为 json 返回的 js 对象作为参数进行传入,顺便处理一下原有的错误处理即可。

在 index.js 中修改路由到 ‘/’ 的 get 请求,使之直接返回一个对象,以测试配置的效果,代码如下

router.get('/', function (req, res, next) {

  res.json(Result.Success('接口测试'));

});

因为对返回数据有固定的格式需求,这里将 json 响应封装为一个类,处理一些重复的操作。完成处理后,待程序重启完毕直接在浏览器访问 http://127.0.0.1:3000 和一个任意不存在的路径,得到如下结果,响应的字符串为 json 字符串,可说明 json 的配置成功,404 访问的信息需要在修改默认的错误处理。

 MongoDB连接、测试

这里使用了 mongoose 进行数据库连接,具体使用方法这里不做说明。

建立连接、建立实体类,比如这里使用的是 Bookmark ,创建一个保存到数据库的方法,代码如下

let mongoose = require('mongoose')

mongoose.connect('mongodb://ip/数据库名')  // 建立连接

// 定义实体
let bookmarkModel = mongoose.model('Bookmark', new mongoose.Schema({
  key: String,
  pwd: String
}, {
  collection: 'home'
}))

// 用于测试的方法,保存实体到数据库
let save = function(key, pwd) {
  let newBookMark = {key, pwd};
  newBookMark = new bookmarkModel(newBookMark);
  newBookMark.save();
}

在 index.js 中定义一个路由,调用这个方法,向定义的路由发送 post 请求进行测试,得到下图所示结果,前端收到了正确的相应,且数据库中生成了指定的数据,说明配置正确,至此数据库连接配置完成,可以进行后续开发。

相关代码 

本实例中,工程根目录为 home。

  • /home/entity

// /home/entity/bookmark.js: 测试用实体

let mongoose = require('./../util/mongodb')

let bookmarkModel = mongoose.model('Bookmark', new mongoose.Schema({
  key: String,
  pwd: String
}, {
  collection: 'home'
}))

module.exports = {
  save(key, pwd) {
    let newBookMark = {key, pwd};
    if(typeof (key) === 'object')  // 如果第一个参数是对象,则保存该对象
      newBookMark = key;
    newBookMark = new bookmarkModel(newBookMark);
    newBookMark.save();
    return Promise.resolve();  // 用于异步处理
  }
}
// /home/entity/ersult.js:Json 响应实体

module.exports = class Result{
  constructor(status=200, info='当前接口无说明信息', obj=null){
    this.status = status
    this.info = info
    this.obj = obj
  }

  static Success = (info, obj=null) => new Result(200, info, obj)
}
  • /home/routes

// /home/routes/index.js: 路由处理

var express = require('express');
var router = express.Router();
var Result = require('./../entity/result');
var bookmarks = require('./../entity/bookmark')
const crypto = require('crypto') // 生成散列值以加密密码

/* GET home page. */
router.get('/', function (req, res, next) {
  res.json(Result.Success('接口测试'));
});

router.post('/save', function (req, res) {
  const md5 = crypto.createHash('md5');
  const pwd = md5.update(req.body.pwd).digest('hex');  // 用于md5密码加密
  const key = req.body.key;
  bookmarks.save(key, pwd).then(() => res.json(Result.Success('保存成功')))
})

module.exports = router;
  • /home/util

// /home/util/mongodb.js: 数据库连接工具

// 建立数据库连接

let config = require('./config')  // 全局配置,代码见本段结尾注释
let mongoose = require('mongoose')

mongoose.connect(config.dbLink, {
  useNewUrlParser: true,  // 处理两个警告
  useUnifiedTopology: true
})

module.exports = mongoose

/* /home/util/config.js

module.exports = {
  dbLink: 'mongodb://localhost/home'
}
*/
  • /home/app.js

// /home/app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');

var Result = require('./entity/result');
var app = express();

// view engine setup, 去除原 view 配置
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);

// 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) {
  var jsonResult = new Result(err.status || 500, err.message, req.app.get('env') === 'development' ? err : {});
  
  // return data to client
  res.status(err.status || 500);
  res.json(jsonResult);
});

module.exports = app;
  • /home/package.json

{
  "name": "home",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "supervisor ./bin/www"
  },
  "dependencies": {
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "morgan": "~1.9.1",
    "body-parser": "1.19.0",
    "mongoose": "*"
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章