• 在庆祝海南建省办经济特区30周年大会上的讲话 2019-10-07
  • 俄罗斯世界杯F组:球迷风采 2019-09-24
  • 彭于晏廖凡曝姜文“精神洁癖” 2019-09-24
  • 苏州大学研究生支教团网上众筹资助留守儿童 2019-09-23
  • 湖北政务微信排行榜第187期出炉 交警类公号表现亮眼 2019-09-19
  • 【奋斗吧2018】风电检修工——荒原上的“听风者” 2019-08-31
  • 母亲节又送康乃馨?送这样的健康佳品才走心 2019-08-30
  • [酷]此文已经把马克思理论、边际理论、人类需求层次理论、生物学理论、心理学理论、社会管理学理论等理论在哲学层面完美融合了! 2019-08-26
  • 兰芝雪纱修颜气垫隔离霜 2019-07-27
  • “鹊桥”中继星顺利进入使命轨道运行 2019-07-27
  • 超越舆情管理的360度信息决策 2019-07-22
  • 视频陶然居变形记:从路边小饭馆到全国餐饮十强 2019-07-21
  • 防震减灾事业发展的重要理论成果 2019-07-20
  • 珠宝配美人!李冰冰大片衣着性感秀身段 2019-07-20
  • 机器人也能拥有“情商”?这个可以有 2019-07-19
  • 香港赛马会六合官方网站:浅谈KOA2 Restful方式路由初探

     更新时间:2019年03月14日 15:07:09   作者:able   我要评论
    这篇文章主要介绍了浅谈KOA2 Restful方式路由初探,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    香港赛马会网站惠泽社绝杀八码 www.mwcrz.tw 前言

    最近考虑将服务器资源整合一下,作为多端调用的API

    看到Restful标准和ORM眼前一亮,但是找了不少版本路由写的都比较麻烦,于是自己折腾了半天

    API库结构

    考虑到全部对象置于顶层将会造成对象名越来长,同时不便于维护,故采取部分的分层结构

    如workflow??槟诘膒rototypes,instances等等,分层的深度定义为层级

    可访问的对象集合(collection)的属性满足Restful设计

     -- workflow(category)
      -- prototypes(collection)
        -- [method] ...
        -- [method] ... 
      -- instances(collection)
     -- users(collection)
       --[method] List     #get :object/
       --[method] Instance   #get :object/:id
     -- ...
     -- ...
    

    RESTFUL API 接口

    将Restful API接口进行标准化命名

    .get('/', ctx=>{ctx.error('路径匹配失败')})        
    .get('/:object', RestfulAPIMethods.List)
    .get('/:object/:id', RestfulAPIMethods.Get)
    .post('/:object', RestfulAPIMethods.Post)
    .put('/:object/:id', RestfulAPIMethods.Replace)
    .patch('/:object/:id', RestfulAPIMethods.Patch)
    .delete('/:object/:id', RestfulAPIMethods.Delete)
    .get('/:object/:id/:related', RestfulAPIMethods.Related)
    .post('/:object/:id/:related', RestfulAPIMethods.AddRelated)
    .delete('/:object/:id/:related/:relatedId', RestfulAPIMethods.DelRelated)

    API对象

    这个文件是来自微信小程序demo,觉得很方便就拿来用了,放于需要引用的根目录,引用后直接获得文件目录结构API对象

    const _ = require('lodash')
    const fs = require('fs')
    const path = require('path')
    
    /**
     * 映射 d 文件夹下的文件为???
     */
    const mapDir = d => {
      const tree = {}
    
      // 获得当前文件夹下的所有的文件夹和文件
      const [dirs, files] = _(fs.readdirSync(d)).partition(p => fs.statSync(path.join(d, p)).isDirectory())
    
      // 映射文件夹
      dirs.forEach(dir => {
        tree[dir] = mapDir(path.join(d, dir))
      })
    
      // 映射文件
      files.forEach(file => {
        if (path.extname(file) === '.js') {
          tree[path.basename(file, '.js')] = require(path.join(d, file))
          tree[path.basename(file, '.js')].isCollection = true
        }
      })
    
      return tree
    }
    
    
    
    // 默认导出当前文件夹下的映射
    module.exports = mapDir(path.join(__dirname))
    
    

    koa-router分层路由的实现

    创建多层路由及其传递关系

    执行顺序为

     1 -- 路径匹配
        -- 匹配到‘/'结束
        -- 匹配到对应的RestfulAPI执行并结束
        -- 继续
     2 -- 传递中间件 Nest
     3 -- 下一级路由
     4 -- 循环 to 1

    const DefinedRouterDepth = 2
    let routers = []
    for (let i = 0; i < DefinedRouterDepth; i++) {
      let route = require('koa-router')()
      if (i == DefinedRouterDepth - 1) {
        // 嵌套路由中间件
        route.use(async (ctx, next) => {
          // 根据版本号选择库
          let apiVersion = ctx.headers['api-version']
          ctx.debug(`------- (API版本 [${apiVersion}]) --=-------`)
           if (!apiVersion) {
            ctx.error('版本号未标记')
            return
          }
          let APIRoot = null
          try {
            APIRoot = require(`../restful/${apiVersion}`)
          } catch (e) {
            ctx.error ('API不存在,请检查Header中的版本号')
            return
          }
          ctx.debug(APIRoot)
          ctx.apiRoot = APIRoot
          ctx.debug('---------------------------------------------')
          // for(let i=0;i<)
          await next()
        })
      }
      route
        .get('/', ctx=>{ctx.error('路径匹配失败')})
        .get('/:object', RestfulAPIMethods.List)
        .get('/:object/:id', RestfulAPIMethods.Get)
        .post('/:object', RestfulAPIMethods.Post)
        .put('/:object/:id', RestfulAPIMethods.Replace)
        .patch('/:object/:id', RestfulAPIMethods.Patch)
        .delete('/:object/:id', RestfulAPIMethods.Delete)
        .get('/:object/:id/:related', RestfulAPIMethods.Related)
        .post('/:object/:id/:related', RestfulAPIMethods.AddRelated)
        .delete('/:object/:id/:related/:relatedId', RestfulAPIMethods.DelRelated)
    
    
      if (i != 0) {
        route.use('/:object', Nest, routers[i - 1].routes())
      }
      routers.push(route)
    }
    let = router = routers[routers.length - 1]
    
    

    Nest中间件

    将ctx.apiObject设置为当前层的API对象

    const Nest= async (ctx, next) => {
      let object = ctx.params.object
      let apiObject = ctx.apiObject || ctx.apiRoot
      if(!apiObject){
        ctx.error('API装载异常')
        return
      }
    
      if (apiObject[object]) {
        ctx.debug(`ctx.apiObject=>ctx.apiObject[object]`)
        ctx.debug(apiObject[object])
        ctx.debug(`------------------------------------`)
        ctx.apiObject = apiObject[object]
      } else {
        ctx.error(`API接口${object}不存在`)
        return
      }
    
    
      await next()
    }

    RestfulAPIMethods

    let RestfulAPIMethods = {}
    let Methods = ['List', 'Get', 'Post', 'Replace', 'Patch', 'Delete', 'Related', 'AddRelated', 'DelRelated']
    for (let i = 0; i < Methods.length; i++) {
      let v = Methods[i]
      RestfulAPIMethods[v] = async function (ctx, next) {
        
        let apiObject = ctx.apiObject || ctx.apiRoot
        if (!apiObject) {
          ctx.error ('API装载异常')
          return
        }
        let object = ctx.params.object
        if (apiObject[object] && apiObject[object].isCollection) {
          ctx.debug(` --- Restful API [${v}] 调用--- `)
          if (typeof apiObject[object][v] == 'function') {
            ctx.state.data = await apiObject[object][v](ctx)
            ctx.debug('路由结束')
            return
            //ctx.debug(ctx.state.data)
          } else {
            ctx.error(`对象${object}不存在操作${v}`)
            return
          }
        }
        ctx.debug(` --- 当前对象${object}并不是可访问对象 --- `)
        await next()
      }
    }
    

    需要注意的点

    1、koa-router的调用顺序
    2、涉及到async注意next()需要加await

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • node.js到底要不要加分号浅析

    node.js到底要不要加分号浅析

    这篇文章主要给大家介绍了关于node.js到底要不要加分号的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • 简单两步使用node发送qq邮件的方法

    简单两步使用node发送qq邮件的方法

    这篇文章主要介绍了简单两步使用node发送qq邮件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • 解决node-sass偶尔安装失败的方法小结

    解决node-sass偶尔安装失败的方法小结

    这篇文章主要介绍了解决node-sass偶尔安装失败的方法小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • node.js中fs.stat与fs.fstat的区别详解

    node.js中fs.stat与fs.fstat的区别详解

    fs.stat和fs.fstat他们都是用来获取文件的状态信息,下面这篇文章主要给大家介绍了关于node.js中fs.stat与fs.fstat区别的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • Node.js复制文件的方法示例

    Node.js复制文件的方法示例

    这篇文章主要介绍了Node.js复制文件的方法,涉及nodejs针对文件流的创建、读取、写入等操作技巧,需要的朋友可以参考下
    2016-12-12
  • node跨域转发 express+http-proxy-middleware的使用

    node跨域转发 express+http-proxy-middleware的使用

    这篇文章主要介绍了node跨域转发 express+http-proxy-middleware的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Nodejs学习笔记之测试驱动

    Nodejs学习笔记之测试驱动

    本文是本系列文章的第二篇,主要是测试针对于web后端的驱动,在开发过程中,在开发完成一段代码后如果负责任而不是说完全把问题交给测试人员去发现的话,这个时候通常都会去做一些手动的测试。
    2015-04-04
  • nodejs高大上的部署方式(PM2)

    nodejs高大上的部署方式(PM2)

    这篇文章主要介绍了nodejs高大上的部署方式(PM2) ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 最新评论

    微信 投稿 投诉建议 在线工具
  • 在庆祝海南建省办经济特区30周年大会上的讲话 2019-10-07
  • 俄罗斯世界杯F组:球迷风采 2019-09-24
  • 彭于晏廖凡曝姜文“精神洁癖” 2019-09-24
  • 苏州大学研究生支教团网上众筹资助留守儿童 2019-09-23
  • 湖北政务微信排行榜第187期出炉 交警类公号表现亮眼 2019-09-19
  • 【奋斗吧2018】风电检修工——荒原上的“听风者” 2019-08-31
  • 母亲节又送康乃馨?送这样的健康佳品才走心 2019-08-30
  • [酷]此文已经把马克思理论、边际理论、人类需求层次理论、生物学理论、心理学理论、社会管理学理论等理论在哲学层面完美融合了! 2019-08-26
  • 兰芝雪纱修颜气垫隔离霜 2019-07-27
  • “鹊桥”中继星顺利进入使命轨道运行 2019-07-27
  • 超越舆情管理的360度信息决策 2019-07-22
  • 视频陶然居变形记:从路边小饭馆到全国餐饮十强 2019-07-21
  • 防震减灾事业发展的重要理论成果 2019-07-20
  • 珠宝配美人!李冰冰大片衣着性感秀身段 2019-07-20
  • 机器人也能拥有“情商”?这个可以有 2019-07-19
  • 棋牌游戏送现金20元 体彩4码全组最大遗漏 赛车六码倍投金额多少 赌场龙虎玩法技巧 后二直选复式杀号公式 红包玩法 通比牛牛出牛牛规律 篮球比赛 重庆肘时彩五星走势图 4肖4码,六肖王论坛