最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談KOA2 Restful方式路由初探

 更新時(shí)間:2019年03月14日 15:07:08   作者:able  
這篇文章主要介紹了淺談KOA2 Restful方式路由初探,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

前言

最近考慮將服務(wù)器資源整合一下,作為多端調(diào)用的API

看到Restful標(biāo)準(zhǔn)和ORM眼前一亮,但是找了不少版本路由寫的都比較麻煩,于是自己折騰了半天

API庫結(jié)構(gòu)

考慮到全部對(duì)象置于頂層將會(huì)造成對(duì)象名越來長,同時(shí)不便于維護(hù),故采取部分的分層結(jié)構(gòu)

如workflow模塊內(nèi)的prototypes,instances等等,分層的深度定義為層級(jí)

可訪問的對(duì)象集合(collection)的屬性滿足Restful設(shè)計(jì)

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

RESTFUL API 接口

將Restful API接口進(jìn)行標(biāo)準(zhǔn)化命名

.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對(duì)象

這個(gè)文件是來自微信小程序demo,覺得很方便就拿來用了,放于需要引用的根目錄,引用后直接獲得文件目錄結(jié)構(gòu)API對(duì)象

const _ = require('lodash')
const fs = require('fs')
const path = require('path')

/**
 * 映射 d 文件夾下的文件為模塊
 */
const mapDir = d => {
  const tree = {}

  // 獲得當(dāng)前文件夾下的所有的文件夾和文件
  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
}



// 默認(rèn)導(dǎo)出當(dāng)前文件夾下的映射
module.exports = mapDir(path.join(__dirname))

koa-router分層路由的實(shí)現(xiàn)

創(chuàng)建多層路由及其傳遞關(guān)系

執(zhí)行順序?yàn)?/p>

 1 -- 路徑匹配
    -- 匹配到‘/'結(jié)束
    -- 匹配到對(duì)應(yīng)的RestfulAPI執(zhí)行并結(jié)束
    -- 繼續(xù)
 2 -- 傳遞中間件 Nest
 3 -- 下一級(jí)路由
 4 -- 循環(huán) 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) => {
      // 根據(jù)版本號(hào)選擇庫
      let apiVersion = ctx.headers['api-version']
      ctx.debug(`------- (API版本 [${apiVersion}]) --=-------`)
       if (!apiVersion) {
        ctx.error('版本號(hào)未標(biāo)記')
        return
      }
      let APIRoot = null
      try {
        APIRoot = require(`../restful/${apiVersion}`)
      } catch (e) {
        ctx.error ('API不存在,請(qǐng)檢查Header中的版本號(hào)')
        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設(shè)置為當(dāng)前層的API對(duì)象

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}] 調(diào)用--- `)
      if (typeof apiObject[object][v] == 'function') {
        ctx.state.data = await apiObject[object][v](ctx)
        ctx.debug('路由結(jié)束')
        return
        //ctx.debug(ctx.state.data)
      } else {
        ctx.error(`對(duì)象${object}不存在操作${v}`)
        return
      }
    }
    ctx.debug(` --- 當(dāng)前對(duì)象${object}并不是可訪問對(duì)象 --- `)
    await next()
  }
}

需要注意的點(diǎn)

1、koa-router的調(diào)用順序
2、涉及到async注意next()需要加await

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • node.js中的http.createClient方法使用說明

    node.js中的http.createClient方法使用說明

    這篇文章主要介紹了node.js中的http.createClient方法使用說明,本文介紹了http.createClient的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • npm查看鏡像源與切換鏡像源方法詳解

    npm查看鏡像源與切換鏡像源方法詳解

    這篇文章主要為大家介紹了npm查看鏡像源與切換鏡像源方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Node.js學(xué)習(xí)之內(nèi)置模塊fs用法示例

    Node.js學(xué)習(xí)之內(nèi)置模塊fs用法示例

    這篇文章主要介紹了Node.js學(xué)習(xí)之內(nèi)置模塊fs用法,結(jié)合實(shí)例形式詳細(xì)分析了node.js內(nèi)置模塊fs的基本功能、用法與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • node.js中express中間件body-parser的介紹與用法詳解

    node.js中express中間件body-parser的介紹與用法詳解

    這篇文章主要給大家介紹了關(guān)于node.js中express中間件body-parser的相關(guān)資料,文章通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • 簡單兩步使用node發(fā)送qq郵件的方法

    簡單兩步使用node發(fā)送qq郵件的方法

    這篇文章主要介紹了簡單兩步使用node發(fā)送qq郵件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • Nest.js使用multer實(shí)現(xiàn)文件上傳功能

    Nest.js使用multer實(shí)現(xiàn)文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了Nest.js鵝湖使用multer實(shí)現(xiàn)文件上傳功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • 基于node.js的fs核心模塊讀寫文件操作(實(shí)例講解)

    基于node.js的fs核心模塊讀寫文件操作(實(shí)例講解)

    下面小編就為大家?guī)硪黄趎ode.js的fs核心模塊讀寫文件操作(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就想給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • nvm管理node版本的詳細(xì)圖文教程

    nvm管理node版本的詳細(xì)圖文教程

    nvm全英文也叫node.js version management,是一個(gè)nodejs的版本管理工具,下面這篇文章主要給大家介紹了關(guān)于nvm管理node版本的詳細(xì)圖文教程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • node.js+postman+mongodb搭建測試注冊(cè)接口的實(shí)現(xiàn)

    node.js+postman+mongodb搭建測試注冊(cè)接口的實(shí)現(xiàn)

    本文主要介紹了node.js+postman+mongodb搭建測試注冊(cè)接口的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • node.js中 redis 的安裝和基本操作示例

    node.js中 redis 的安裝和基本操作示例

    這篇文章主要介紹了node.js中 redis 的安裝和基本操作,結(jié)合實(shí)例形式分析了node.js中Redis下載、安裝、數(shù)據(jù)類型及基本操作技巧,需要的朋友可以參考下
    2020-02-02

最新評(píng)論

永康市| 丽水市| 宜春市| 连山| 北流市| 上犹县| 怀安县| 邢台县| 鹤岗市| 石林| 丽水市| 云南省| 三台县| 孟州市| 芦山县| 长阳| 博兴县| 大丰市| 佛山市| 治县。| 大竹县| 贵州省| 大关县| 荆州市| 东丽区| 紫金县| 甘谷县| 明光市| 城口县| 土默特右旗| 城市| 团风县| 蓝山县| 兴义市| 绵阳市| 剑阁县| 定远县| 沁水县| 寿阳县| 甘德县| 新建县|