淺談KOA2 Restful方式路由初探
前言
最近考慮將服務(wù)器資源整合一下,作為多端調(diào)用的API
看到Restful標(biāo)準(zhǔn)和ORM眼前一亮,但是找了不少版本路由寫(xiě)的都比較麻煩,于是自己折騰了半天
API庫(kù)結(jié)構(gòu)
考慮到全部對(duì)象置于頂層將會(huì)造成對(duì)象名越來(lái)長(zhǎng),同時(shí)不便于維護(hù),故采取部分的分層結(jié)構(gòu)
如workflow模塊內(nèi)的prototypes,instances等等,分層的深度定義為層級(jí)
可訪問(wèn)的對(duì)象集合(collection)的屬性滿(mǎn)足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,覺(jué)得很方便就拿來(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}并不是可訪問(wèn)對(duì)象 --- `) await next() } }
需要注意的點(diǎn)
1、koa-router的調(diào)用順序
2、涉及到async注意next()需要加await
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Node.js的Koa框架上手及MySQL操作指南
- 淺談Koa2框架利用CORS完成跨域ajax請(qǐng)求
- node koa2實(shí)現(xiàn)上傳圖片并且同步上傳到七牛云存儲(chǔ)
- 利用Node.js+Koa框架實(shí)現(xiàn)前后端交互的方法
- 客戶(hù)端(vue框架)與服務(wù)器(koa框架)通信及服務(wù)器跨域配置詳解
- nuxt框架中路由鑒權(quán)之Koa和Session的用法
- 詳解express與koa中間件模式對(duì)比
- 淺談在koa2中實(shí)現(xiàn)頁(yè)面渲染的全局?jǐn)?shù)據(jù)
- node使用Koa2搭建web項(xiàng)目的方法
相關(guān)文章
測(cè)試驅(qū)動(dòng)ChatGPT編程示例詳解
這篇文章主要為大家介紹了測(cè)試驅(qū)動(dòng)ChatGPT編程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03詳解如何使用node.js的開(kāi)發(fā)框架express創(chuàng)建一個(gè)web應(yīng)用
這篇文章主要介紹了詳解如何使用node.js的開(kāi)發(fā)框架express創(chuàng)建一個(gè)web應(yīng)用,網(wǎng)上各種搜索后,整理了下快速搭建express框架的步驟。非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-12-12Node.js實(shí)現(xiàn)用戶(hù)評(píng)論社區(qū)功能(體驗(yàn)前后端開(kāi)發(fā)的樂(lè)趣)
這篇文章主要介紹了Node.js實(shí)現(xiàn)用戶(hù)評(píng)論社區(qū)(體驗(yàn)前后端開(kāi)發(fā)的樂(lè)趣) ,需要的朋友可以參考下2019-05-05詳解基于node.js的腳手架工具開(kāi)發(fā)經(jīng)歷
這篇文章主要介紹了詳解基于node.js的腳手架工具開(kāi)發(fā)經(jīng)歷,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01提升node.js中使用redis的性能遇到的問(wèn)題及解決方法
本文中提到的node redis client采用的基于node-redis封裝的二方包,因此問(wèn)題排查也基于node-redis這個(gè)模塊。接下來(lái)通過(guò)本文給大家分享提升node.js中使用redis的性能2018-10-10node.js 基于 STMP 協(xié)議和 EWS 協(xié)議發(fā)送郵件
這篇文章主要介紹了node.js 基于 STMP 協(xié)議和 EWS 協(xié)議發(fā)送郵件的示例,幫助大家更好的理解和使用node.js,感興趣的朋友可以了解下2021-02-02詳解通過(guò)源碼解析Node.js中cluster模塊的主要功能實(shí)現(xiàn)
這篇文章主要介紹了詳解通過(guò)源碼解析Node.js中cluster模塊的主要功能實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05windows系統(tǒng)下安裝npm(Node.js)方法教程
在Windows環(huán)境下進(jìn)行Node.js的安裝并不是一件復(fù)雜的事情,但是在安裝過(guò)程中需要注意一些細(xì)節(jié),下面這篇文章主要給大家介紹了關(guān)于windows系統(tǒng)下安裝npm(Node.js)的相關(guān)資料,需要的朋友可以參考下2023-12-12