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之前才能工作。