国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

淺談KOA2 Restful方式路由初探

2019-11-19 11:59:38
字體:
供稿:網(wǎng)友

前言

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

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

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

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

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

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

 -- 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對象

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

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分層路由的實現(xiàn)

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

執(zhí)行順序為

 1 -- 路徑匹配
    -- 匹配到‘/'結(jié)束
    -- 匹配到對應(yīng)的RestfulAPI執(zhí)行并結(jié)束
    -- 繼續(xù)
 2 -- 傳遞中間件 Nest
 3 -- 下一級路由
 4 -- 循環(huán) to 1

const DefinedRouterDepth = 2let routers = []for (let i = 0; i < DefinedRouterDepth; i++) {  let route = require('koa-router')()  if (i == DefinedRouterDepth - 1) {    // 嵌套路由中間件    route.use(async (ctx, next) => {      // 根據(jù)版本號選擇庫      let apiVersion = ctx.headers['api-version']      ctx.debug(`------- (API版本 [${apiVersion}]) --=-------`)       if (!apiVersion) {        ctx.error('版本號未標(biāo)記')        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設(shè)置為當(dāng)前層的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}] 調(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(`對象${object}不存在操作${v}`)        return      }    }    ctx.debug(` --- 當(dāng)前對象${object}并不是可訪問對象 --- `)    await next()  }}

需要注意的點

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 汕头市| 鹤山市| 偃师市| 广东省| 宁乡县| 扎囊县| 临沂市| 宁国市| 皮山县| 西藏| 宣化县| 唐山市| 宁河县| 吐鲁番市| 珠海市| 马山县| 柳州市| 金湖县| 察哈| 青神县| 光山县| 顺平县| 淮南市| 新乡县| 呼图壁县| 铜鼓县| 泸西县| 邮箱| 新巴尔虎左旗| 琼海市| 南华县| 南康市| 海盐县| 化德县| 盘山县| 蕲春县| 淄博市| 奉新县| 阿拉善盟| 伽师县| 长宁县|