管理后台-后端-Node.js篇

本文介绍如何使用Node.js和Express框架结合Sequelize ORM进行Web应用开发,包括环境搭建、数据库建模、CRUD操作及扩展协议实现。

Node.js的框架种类繁多,我们选用了Express做为web框架,结合Sequelize做为数据库ORM框架。


我们先来搭建基础环境

> yum install epel-release    ### 让yum支持nodejs安装
> yum install nodejs    ### 安装nodejs
> yum install npm    ### 安装npm(用来安装nodejs第三方库)
> mkdir RestfulProject    ### 创建项目目录
> cd RestfulProject
> npm install express-generator    ### 安装Express
> node_modules/.bin/express -f    ### Express创建项目框架
> npm install    ### 安装框架需要的第三方库
> npm install --save sequelize sequelize-cli sqlite3 basic-auth cors
> node_modules/.bin/sequelize init    ### Sequelize初始化
> PORT=8000 npm start    ### 启动服务

顺利的话浏览器访问如下
这里写图片描述

nodejs默认是将js加载在内存中,对于代码的改变,需要重启服务才能生效,读者可以安装supervisor或者hotnode插件来做auto-reload。


数据库建模

1)配置数据库连接

// config/config.json
"development": {
    ...
    "dialect": "sqlite",
    "storage": "db.sqlite3"
  },

2)创建migration

> node_modules/.bin/sequelize model:create --name News --attributes title:string,content:text,create_time:date

上述指令会在子目录migrations创建一个带时间戳的migration文件,在子目录models创建一个数据库模型news.js

3)cli执行migrate

> node_modules/.bin/sequelize db:migrate

上述指令会在数据库中创建news表


书写最简单的CRUD

// routes/news.js
var News  = require('../models').News;
var express = require('express');
var router = express.Router();

router.post('/',function(req,res){
    var form = req.body;
    form.create_time = Date.now();
    News.create(form).then(function(data){
        res.status(201).json(data);
    });
})
router.get('/', function(req, res) {
    News.findAll().then(function(data){
        res.json(data);
    })
});

router.route('/:id/')
.get(function(req,res){
    News.findOne({
        where:{
            id:req.params.id
        }
    })
    .then(function(data){
        res.json(data);
    });
})
.put(function(req,res){
    News.update(req.body,{
        where:{
            id:req.params.id
        }
    })
    .then(function(data){
        res.json({})
    });
})
.delete(function(req,res){
    News.destroy({
        where:{
            id:req.params.id
        }
    })
    .then(function(data){
        res.json({})
    });
});

module.exports = router;

加入路由

// app.js
...
var news = require('./routes/news');
var app = express();
...
app.use('/news', news);

使用postman测试接口


书写扩展协议-批量删除

// routes/news.js
...
router.delete('/deletes/',function(req,res){
    News.destroy({
        where:{
            id:{
                $in:req.query.ids.split(',')
            }
        }
    })
    .then(function(){
        res.json({})
    })
})

书写扩展协议-搜索+分页

// routes/news.js
var PAGE_SIZE=50;
...
router.get('/', function(req, res) {
    var search = req.query.search||'';
    var page = parseInt(req.query.page||1);
    News.findAndCountAll({
        where:{
            title:{
                $like:'%'+search+'%',
            }
        },
        order:[
            ['create_time','DESC'],
        ],
        limit:PAGE_SIZE,
        offset:PAGE_SIZE*(page-1),
    })
    .then(function(data){
        var total_count = data.count;
        var page_count = Math.floor(total_count/PAGE_SIZE);
        if(total_count%PAGE_SIZE>0){
            page_count++;
        }
        data = {
            total_count:data.count,
            page_count:page_count,
            next:page<page_count,
            previous:page>1,
            results:data.rows,
        }
        res.json(data)
    });
})

补全认证接口
求简,我们直接在index.js里面注入认证的路由

// routes/index.js 
...
router.get('/auth/info', function(req, res, next) {
  res.json({username:'test',userid:1});
});

加入BasicAuth认证
github上有写好的中间件basic-auth-connect供下载,但是Express4对于中间件的架构做了调整,按照该中间件文档使用是无效的,所以我们自己来手写中间件

// utils.js
/**
 * Your utility library for express
 */

var basicAuth = require('basic-auth');

/**
 * Simple basic auth middleware for use with Express 4.x.
 *
 * @example
 * app.use('/api-requiring-auth', utils.basicAuth('username', 'password'));
 *
 * @param   {string}   username Expected username
 * @param   {string}   password Expected password
 * @returns {function} Express 4 middleware requiring the given credentials
 */
exports.basicAuth = function(username, password) {
  return function(req, res, next) {
    var user = basicAuth(req);

    if (!user || user.name !== username || user.pass !== password) {
      res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
      return res.status(401).json();
    }

    next();
  };
};

入口注入该中间件

// app.js
...
var utils = require('./utils');
...
app.use(utils.basicAuth('admin', '111111'));
app.use('/', routes);
...

加入CORS跨域访问支持

//app.js
...
var cors = require('cors');
...
app.use(cors());
app.use(utils.basicAuth('admin', '111111'));
...

注意,cors必须放置在BasicAuth之前才能工作。

这个系统其实是出于学习nodejs的目的而改写的系统。 原来的系统前端使用了extjs4.2.1,后端使用了PHP5.4和ZEND框架开发,后台数据库是用mongodb2.2.2。 我抽离出了原来系统中的账户管理,角色管理,菜单管理,权限管理这4个部分, 我想这4个部分,基本上所有的系统都会用到。具有一定的普遍性。所以将这4个部分用nodejs重新改写了。 该系统目前使用模块有express,ejs,connect-mongo,mongodb,express-partials,connect-flash,fibers,wind等 其实wind模块这次系统中没有使用。可以将它排除出去。我是出于学习wind的目的,才加入这个模块的。 本来准备使用wind模块,是为了实现同步的目的,由于后来改用了fibers模块之后,就没有使用它。这里说明一下 不是fibers要比wind好,而是我暂时不能理解wind,或则是说对wind的研究不够吧。 众所周知nodejs是推崇异步模式。但是这个系统是从php过来的,而php的代码是同步模式的写法,所以为了在改写的过程中 希望 1是代码改动最少 2是同步写法更加适合思维习惯。而且代码可读性高的目的,用到了fibers。 这个系统的源代码中有些js文件里保留了一些原来的PHP代码,这是出于代码对比的目的。 是让大家了解原来的php代码是怎么实现的,用nodejs之后是如何改写的。通过对比,大家会发现 其实通过使用fibers之后,几乎两者是一模一样的。 还有源代码中还保留了一些被注释掉的函数,有些是用到了wind,有些是用到了fibers,有些是直接异步的写法。 这些内容都是在开发过程中我不断尝试后的产物。我花了1周的时间才实现了一个递归的调用,而且还是同步的方式。 到目前为止,我还不能理解在异步模式下实现递归调用函数。比如说源代码中有个函数getMenuTree,菜单下面可能有子菜单, 子菜单的下面可能还有菜单。所以是一个递归的过程。我现在是同步的写法实现了这个函数,如果有人能够提供异步写法实现的递归函数并 emai给我,我不胜荣幸。 在使用本系统之前,必须要安装nodejs 0.10.10,mongodb2.2.2,python2.7.5至于安装的方法请googel解决。 将源代码下载之后,解压到某个目录下,比如说d:\nodejs\umav4simple目录。 进入到那个目录, a)运行以下命令 npm install express npm install ejs npm install connect-mongo npm install mongodb npm install express-partials npm install connect-flash npm install fibers npm install wind 尽管在源代码中已包含了这些模块,但是最好还是要重新运行一遍。 因为有些模块可能需要重新的编译。 比如说fibers模块,我在window下运行npm install fibers的时候编译了一个win32-ia32-v8-3.14 而在linux下重新编译了linux-ia32-v8-3.14。所以说根据操作系统的不同,可能会有一些不同。 以免造成想不到的错误。 b)打开settings.js,并且将你的mongodb的设置改写并保存。 c)运行node app.js或则node cluster.js 如果没有提示错误的话,那么就说明环境配置成功了。 d)通过以下的URL可以在mongodb中追加一些数据,不过只能运行一次。否则会重复追加数据。 浏览器上输入 http://localhost:3000/admin/index/install 做完之后, 浏览器上输入http://localhost:3000/ 就通过用户名admin 密码adminadmin进行登录,并使用这个系统了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值