zoukankan      html  css  js  c++  java
  • Restful接口规范

    Rest,即Resources Representational State Transfer(资源表现层状态转化)。

      ·资源(Resources),网络上的一个实体,每种资源对应一个特定的URI(统一资源标识符)

      ·表现层(Representational),资源呈现的形式,比如:json

      ·状态转化(State Transfer),http协议里,四个表示操作方式的基本操作

    Restful API设计规范

      ·使用http协议

      ·url中只有名词,如add、delete等动词不应出现

      ·不同操作由动词来区分:get,post(新建),put(更新,客户端需提供改变后的完整资源),patch(更新,客户端只需提供资源改变的属性),delete(删除)

      ·查询字符串中指定过滤条件

    结果

      · GET /collection:返回资源对象的列表(数组)

      · GET /collection/id:返回单个资源对象

      · POST /collection:返回新生成的资源对象

      · PUT /collection/id:返回完整的资源对象

      · PATCH /collection/id:返回更新后的完整资源对象

      · DELETE /collection/id:返回一个空资源

    restfulAPI.js

    var express = require('express');
    var app = express();
    var path = require('path');
    var bodyParser = require('body-parser');
    app.set('view engine','ejs');
    //path.resolve  取当前目录的绝对路径
    app.set('views',path.resolve());
    app.use(bodyParser.urlencoded({extended:true}));
    /*app.use(bodyParser.raw({
        type:'application/!*'
    }));
    app.use(bodyParser.text({
        type:'text/!*'
    }));*/
    app.use(function(req,res,next){
        console.log('body',req.body);
        next();
    });
    app.use(function(err,req,res,next){
        console.error(err);
        next();
    });
    /*app.post('/raw',function(req,res){
        res.send(req.body);
    });*/
    var users = [{id: 1, name: 'zfpx1',mny:100}, {id: 2, name: 'zfpx2',mny:100}];
    /**
     * 1. 获取所有的用户 curl -v -H 'accept:text/html'  http://localhost:8080/users
     * 2.
     */
    //1.获取所有的用户
    app.get('/users', function (req, res) {
        //Accept:text/html,application/xml;q=0.9,image/webp,*/*;q=0.8。获取请求中accept权重最高的格式
        var accept = req.headers['accept'];
        var acceptType = accept.split(',').map(function (item) {
            var values = item.split(';');
            return {
                type: values[0],//需要的文件类型
                q: values[1] ? values[1].split('=')[1] : 1 //权重 默认是1
            }
            //用优先级进行排序,取排名最高那个
        }).sort(function (a, b) {
            return b.q - a.q;
        })[0].type;
        console.log(acceptType);
        if(acceptType == 'text/plain'){
            res.setHeader('Content-Type',acceptType);
            res.send(users);
        }else if(acceptType == 'text/html'){
            //设置响应类型
          res.setHeader('Content-Type',acceptType);
            //渲染模板
           res.render('users.ejs',{
               users:users
           });
        }else{
            res.send(users);
        }
    });
    
    //返回某个用户信息 路径参数
    //curl  http://localhost:8080/users/1  使用函数过滤器过滤
    app.get('/users/:id', function (req, res) {
         var id = req.params.id;
        var filteredUsers = users.filter(function(user){
            return user.id == id;
        });
       res.send(filteredUsers.length>0?filteredUsers[0]:'此用户不存在');
    });
    
    //新增加用户
    // -X 指定请求方法 --data 指定请求体的数据
    //curl -X POST --data "name=zfpx3"  http://localhost:8080/users  用body-parser获取请求体
    app.post('/users', function (req, res) {
      var addedUser = req.body;
        if(addedUser){
            //为增加的用户赋一个最大的ID
            addedUser.id = users[users.length-1].id+1;
            users.push(addedUser);
            //当新增加一个资源的时候要返回新生成的资源完整对象
            res.send(addedUser);
        }else{
            res.send({msg:'增加资源失败'});
        }
    });
    //整体更新全部属性
    // curl -X PUT --data "id=2&name=zfpx20"  http://localhost:8080/users/2
    app.put('/users/:id',function(req,res){
        var putUser = req.body;
        if(putUser){
            for(var i=0;i<users.length;i++){
                //判断当前用户和用户传进来要更新的用户ID是否一致
                if(users[i].id == req.params.id){
                    users[i] = putUser;//把老的对象整体替换成新的对象
                   break;
                }
            }
            res.send(putUser);
        }else{
            res.send({msg:'更新资源失败'});
        }
    });
    //局部更新 请求体里只传要更新的字段
    //curl -X PATCH --data "name=zfpx200"  http://localhost:8080/users/2
    app.patch('/users/:id',function(req,res){
        var updatedFields = req.body;
        if(updatedFields){
            for(var i=0;i<users.length;i++){
                //判断当前用户和用户传进来要更新的用户ID是否一致
                if(users[i].id == req.params.id){
                  for(var attr in updatedFields){
                      //用新的值替换旧的值
                      if(updatedFields.hasOwnProperty(attr))
                        users[i][attr] = updatedFields[attr];
                  }
                    res.send(users[i]);
                    break;
                }
            }
    
        }else{
            res.send({msg:'更新资源失败'});
        }
    });
    //删除
    //curl -X DELETE   http://localhost:8080/users/2  end不能接收对象参数,send可以接收
    app.delete('/users/:id',function(req,res){
        /*for(var i=0;i<users.length;i++){
            if(users[i].id == req.params.id){
                users.splice(i,1);
                res.send({});
                return;
            }
        }*/
        users  = users.filter(function(user){
               return user.id != req.params.id;
        });
        res.send({msg:'删除失败'});
    });
    //以资源为中间 URL里不要包含动词 比如从id 1转账到 id 2,此时不是简单的restful形式,可以灵活变化 但定义url时避免使用动词
    app.post('/transaction/:fromId/:toId',function(){
      var money = req.body.money;
    
    });
    
    app.listen(8080);

     tips:

    /**
     * map 替换所有的元素
     * filter 过滤数组中的元素
     * reduce 聚合
     * reduceRight 从右往左聚合
     * some 有一个满足就可以
     * every 全部满足条件
     * indexOf 第一个索引
     * lastIndexOf 最后索引
     */
    var nums = [1,2,3,1,6,4];
    /**
     *  会依次把数组中的每一元素传入next
     *  每次返回值会传入下一次的current
     *  最后得到一个最终值
     *  获取元素最大值
     */
    var s = nums.reduce(function(current,next){
        return current>next?current:next;
    },0);
    console.log(s);

     

  • 相关阅读:
    Visual Studio 2010使用Visual Assist X的方法
    SQL Server 2000 评估版 升级到 SQL Server 2000 零售版
    双网卡多网络单主机同时访问
    开发即过程!立此纪念一个IT新名词的诞生
    delphi dxBarManager1 目录遍历 转为RzCheckTree2树
    5320 软件集合
    delphi tree 从一个表复制到另一个表
    DELPHI 排课系统课表
    长沙金思维 出现在GOOGLE的 金思维 相关搜索里啦!!
    如何在DBGrid的每一行前加一个单选框?
  • 原文地址:https://www.cnblogs.com/web-fengmin/p/6423402.html
Copyright © 2011-2022 走看看