NodeJS+Express下构建后端MVC文件结构
关于MVC的结构大体上有两种方式,其一按照层级进行文件夹分类,其二是按照业务进行文件夹分类。关于这个demo相关的业务简单,所以暂采用第一种的方式,当然实际当中很恨复杂的项目可以采用两种方式相结合的方式来进行!
不多说费,然后我们具体结构,直接上图:
github地址:https://github.com/FicoHu/nodeserver
nodesv:根目录,作为整个web项目的跟文件夹。
app: 作为整个后端服务的文件夹,我们这次说的重点就是这个文件夹下的结构。
public作为整个项目前端的文件夹,随后的章节再进行说明。
app下4个文件夹:
- controllers,表示控制层
- libs,封装的一些通用模块,例如日志操作模块、文件操作模块等
- model,表示数据层
- routes,表示路由
- views,表示视图。
需要注意一些几点:
关于文件名称,采用 对象名+服务端+层级 的方式进行的命名,例如:doc.server.controller.js,表示服务端的文档模块的控制层文件。
重点说明一下,controller、model、route层里面放置的内容:
doc.server.controller.js,这个模块里面的数据操作进行封装成方法,然后对外进行公开,例如,这个文档模块里面,增加创建、查看列表等方法。
var mongoose = require("mongoose"); var docModel = require("../models/doc.server.model"); module.exports = { create: function(req, res, next) { // var docEntity = new docModel(req.body); var docEntity = new docModel({ title: 'aaa', type: 'dd', ext: '.jpg', size: 1024, Content: 'dsf ', created: Date.now(), creater: 'dsfadf ' }); console.log(docEntity); docModel.create(docEntity, function(err) { if (err) return next(err); return res.json(docEntity); }); }, getList: function(req, res, next) { var pagesize = parseInt(req.query.pagesize, 10) || 10; var pagestart = parseInt(req.query.pagestart, 10) || 1; console.log(pagesize + " " + pagestart); docModel.find() .skip((pagestart - 1) + pagestart) .limit(pagesize).exec(function(err, results) { if (err) return next(err); if (!results) return next(new Error('doc not found')); return res.json(results); //return res.json({id:1,name:"dddd"}); }); }, getById: function(req, res, next) { //if (!did) return next(new Error('did not found')); console.log( req.params.did); docModel.findOne({ _id: req.params.did }) .exec(function(err, results) { if (err) return next(err); if (!results) return next(new Error('doc not found')); return res.json(results); }); } };
doc.server.model.js,作为这个模块的数据文件,定义这个模块内容的相关字段。
var mongoose = require("mongoose"); var docSchema = new mongoose.Schema({ title: String, pid: { type: mongoose.Schema.Types.ObjectId, index: true }, uid: { type: mongoose.Schema.Types.ObjectId, index: true }, type: { type: Number, //1标识文档,2标识图片,3标识视频,4标识其他 index: true, default: 0 }, ext: String, size: { type: Number, //文件大小,文件夹为0 default: 0 }, content: Buffer, docurl: String, status: { type: Number, //0标识为正常,1标识分享 default: 0 }, isflag: { type: Number, //0标识为正常,1标识删除 default: 0 }, created: { type: Date, default: Date.now }, creater: { name: String, uid: mongoose.Schema.Types.ObjectId }, updated: { type: Date, default: Date.now }, updater: { name: String, uid: mongoose.Schema.Types.ObjectId } }); var docModel = db.model("docs", docSchema); module.exports = docModel;
doc.server.route.js,作为这个模块的路由文件。
var express = require('express'); var docRouter = express.Router(); var docController=require('../controllers/doc.server.controller'); docRouter.get('/getList',docController.getList); docRouter.get('/create',docController.create); docRouter.get('/getById/:did',docController.getById); module.exports = docRouter;
这些文件已经知道具体的作用,拿这些代码是如何一个运行顺序呢?
在web服务启动时,就已经加载了app.js ,需要在appjs里面定义一下路由,
var docRoute = require('./app/routes/doc.server.route.js');
app.use('/doc', docRoute);
1、用户发起请求,http://www.xxxxx.club/doc/getList
2、node server,发现这个app已经设置了doc的路由
3、然后node server,解析docRoute,定位到./app/routes/doc.server.route.js里面到详细。
4、根据详细路由,然后指定控制器里面到具体操作,例如:docRouter.get('/getList',docController.getList);,
5、进入控制器,执行getList操作。
6、若getList操作涉及model层,则调用model层相关数据结构。
6、然后由控制器将数据返回给用户。
这样则是整个mvc到请求过程!