Node.js开发Web后台服务(八)之RESTful(表述性状态转移)

六、RESTful(表述性状态转移)

REST是英文Representational State Transfer的缩写,中文称之为“表述性状态转移”,基于HTTP协议是另一种服务架构,传递是JSON、POX(Plain Old XML)而不是SOAP格式的数据充分利用HTTP谓词(Verb)侧重数据的传输,业务逻辑交给客户端自行处理.REST是一种分布式服务架构的风格约束,像Java、.Net(WCF、WebAPI)都有对该约束的实现,使URL变得更加有意义,更加简洁明了,如:

http://www.zhangguo.com/products/1 get请求 表示获得所有产品的第1个
http://www.zhangguo.com/products/product post请求 表示添加一个产品
http://www.zhangguo.com/products/1/price get请求 表示获得第1个产品的价格
http://www.zhangguo.com/products/1 delete请求 删除编号为1的产品

REST设计需要遵循的原则
网络上的所有事物都被抽象为资源(resource);
每个资源对应一个唯一的资源标识符(resource identifier);
通过通用的连接器接口(generic connector interface)对资源进行操作;
对资源的各种操作不会改变资源标识符;
所有的操作都是无状态的(stateless)

谓词
GET
表示查询操作,相当于Retrieve、Select操作
POST
表示插入操作,相当于Create,Insert操作
PUT
表示修改操作,相当于Update操作
DELETE
表示删除操作,相当于Delete操作

其它还有:

63651-20161223101344557-1727952968.png

NodeJS+Express可以很容易的实现REST

application/x-www-form-urlencoded
multipart/form-data
application/json
res.setHeader('Content-Type', 'application/json;charset=utf-8');

示例代码cars.js:

var express = require('express');var router = express.Router();var _= require('lodash');var cars=[];
cars.push({id:201701,name:"BMW",price:190,speed:"210km/h",color:"白色"});
cars.push({id:201702,name:"BYD",price:25,speed:"160km/h",color:"红色"});
cars.push({id:201703,name:"Benz",price:300,speed:"215km/h",color:"蓝色"});
cars.push({id:201704,name:"Honda",price:190,speed:"170km/h",color:"黑色"});
cars.push({id:201705,name:"QQ",price:130,speed:"210km/h",color:"白色"});
/* Get */
/*获得所有汽车*/
/*url /cars/*/
router.get('/', function(req, res, next) {
    res.json(cars);
});
/*Get*/
/*获得汽车通过id*/
/*url:/cars/:id  */
router.get('/:id', function(req, res, next) {     
//从路径中映射参数,转换成数字
      var id=parseInt(req.params.id);      
      var car=_.find(cars,{id:id});
      res.json(car);
});
/*Post*/
/*添加汽车*/
/*url:/cars/car  */
router.post('/car', function(req, res, next) {      
        var car=req.body;  
        //从请求正文中获得json对象
      car.id=_.last(cars).id+1;  
      //将编号修改为最后一辆车的编号+1
      cars.push(car);  //将汽车对象添加到集合中
      res.json(car);  //将添加成功的车以json的形式返回
});
/*Put*/
/*修改汽车*/
/*url:/cars/car  */
router.put('/car', function(req, res, next) {      
        var car=req.body;  //从请求正文中获得json对象      
        console.log(req.body);      
        var index=_.findIndex(cars,{id:parseInt(car.id)});  //根据id获得车在集合中的下标      
      cars[index]=car;  //替换原对象
      //res.json(car);  //将修改后的车以json的形式返回
      res.send({status:"success", message:"更新成功!"});  
});
/*Delete*/
/*删除汽车*/
/*url:/cars/:id  */
router.delete('/id/:id', function(req, res, next) {      
//获得url中的编号参数
      var id=parseInt(req.params.id);      
      var index=_.findIndex(cars,{id:id});  //根据id获得车在集合中的下标
      cars.splice(index,1);   //在cars数组中删除下标从index开始的1条数据
      res.send({status:"success", message:"删除成功!"});  
});
module.exports = router;

示例代码app.js:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var pdts = require('./routes/product');
var task = require('./routes/task');
var cars = require('./routes/cars');
var app = express();//指定视图引擎为ejs
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
app.use('/pdt', pdts);
app.use("/task",task);
app.use("/cars",cars);
// catch 404 and forward to error handler
app.use(function(req, res, next) {  
    var err = new Error('Not Found');
  err.status = 404;
  next(err);
});// error handlerapp.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 : {};  // render the error page
  res.status(err.status || 500);
  res.render('error');
});
module.exports = app;

/* Get */
/*获得所有汽车*/
/*url /cars/*/

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第1张图片

/*Get*/
/*获得汽车通过id*/
/*url:/cars/:id */

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第2张图片

/*Post*/
/*添加汽车*/
/*url:/cars/car */

 Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第3张图片

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第4张图片

参数中的json格式一定要使用标准格式,注意引号,注意Content-Type,默认的Content-Type类型是:application/x-www-form-urlencoded

/*Put*/
/*修改汽车*/
/*url:/cars/car */

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第5张图片

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第6张图片

/*Delete*/
/*删除汽车*/
/*url:/cars/:id */

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第7张图片

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第8张图片

node.js跨域

修改app.js文件拦截所有的请求,修改头部

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "content-type");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    if(req.method == "OPTIONS") {
        res.send("200");
    } else {
        next();
    }
});

结果:

Node.js开发Web后台服务(八)之RESTful(表述性状态转移)_第9张图片

追梦猪git地址:https://github.com/jiawenguang/NodeJsWebServer

本文章参考张果大大的教程实现

张果大大git地址:

https://coding.net/u/zhangguo5/p/NodeJSExpress/git

https://coding.net/u/zhangguo5/p/NodeJS001/git

特别鸣谢!

你可能感兴趣的:(Node.js开发Web后台服务(八)之RESTful(表述性状态转移))