真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

KOA2中Restful方式路由的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)KOA2中Restful方式路由的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

10年積累的成都網(wǎng)站建設(shè)、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有嘉陵免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

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

考慮到全部對(duì)象置于頂層將會(huì)造成對(duì)象名越來(lái)長(zhǎng),同時(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è)文件是來(lái)自微信小程序demo,覺得很方便就拿來(lái)用了,放于需要引用的根目錄,引用后直接獲得文件目錄結(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)選擇庫(kù)
      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

關(guān)于“KOA2中Restful方式路由的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


文章名稱:KOA2中Restful方式路由的示例分析
文章地址:http://weahome.cn/article/gcpepp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部