Koa在實際的業務場景中,路由如何做分割?【文末留言送書】

大家好,我是若川。文末留言送書,具體規則文末說明。另外為了鼓勵大家多寫源碼共讀筆記,我會在寫了5次及以上筆記的作者群里也抽獎送這本書。以后也會有更多福利傾斜。

3ce37dcd64660c068fedf25387bf3e86.png

導讀:Koa是一個Node框架,在Node開源社區中,Koa的使用范圍非常廣,掌握Koa的使用方法,就能輕松應對業界的一些BFF框架。本文介紹Koa在實際的業務場景中,路由如何做分割。

a45c84c43a2d481224b497b263be28d1.png

?

作者:劉江虹

來源:華章計算機(hzbook_jsj)

在實際的復雜業務場景中,簡單的路由堆砌會使得路由文件越來越大,隨著后續的項目不斷迭代,開發人員的不斷更替,如果所有的路由都寫在一個文件里,會使得路由模塊變得越來越難維護。

那么,Koa的項目要如何去解決路由難維護的問題呢?對于這個問題,由抖音電商前端架構師撰寫的《Koa開發:入門、進階與實戰》給出了很好的解決方案,下面讓我們結合這本書的內容來詳細看一看Koa中路由的使用技巧。

在介紹路由分割以及文件路由之前,我們回憶一下koa-router這個中間件的使用。假如需要兩個路由,一個是獲取貨物信息,一個是獲取用戶信息,那用koa-router實現的代碼應該是這樣的:

const?Koa?=?require('koa')const?app?=?new?Koa()const?Router?=?require('koa-router')const router = new Router()router.get('/goods/getInfo',?async?(?ctx?)?=>?{ctx.body?=?'this?is?koa?book.'})router.get('/user/getInfo',?async?(?ctx?)?=>?{ctx.body?=?'my?name?is?liujianghong.'})app.use(router.routes())app.listen(4000,?()?=>?{console.log('server?is?running,?port?is?4000')})

這樣的寫法相信讀者應該已經掌握了,但這樣寫其實有個弊端,如果在一個實際的項目中,Node.js層的接口可能會很多,所有的路由都放在一個文件里,最終會變得越來越難維護,那實戰中我們應該如何維護好路由的編寫呢?本節將闡述兩種方案。

1、路由分割

所謂路由分割,就是把所有路由按照類別劃分,分別維護在不同的文件里。在實際的項目中,通常情況下,一個項目是由多人開發維護的,比如張三只維護貨物相關的路由,李四只維護用戶相關的路由,如果讓兩人在一個文件里維護,那隨著項目越來越大,接口越來越多,難免會出現不好維護的情況。所以,路由分割就一定程度上解決了這樣的問題,讓路由易迭代、易維護。

本文提到的實例中有兩個類型的路由,一個是貨物的,一個是用戶的,那么接下來,我們就對這兩類路由進行分割。首先,按照類型可以把不同的路由寫在不同的文件里,貨物的路由文件代碼如下:

//?routers/goods.jsconst?Router?=?require('koa-router')const?router?=?new?Router()//?設置路由前綴router.prefix('/goods')router.get('/getInfo',?(ctx,?next)=>{ctx.body?=?"this?is?koa?book."})module.exports?=?router

用戶的路由文件代碼如下:

//?routers/user.jsconst?Router?=?require('koa-router')const?router?=?new?Router()router.prefix('/user')router.get('/getInfo',?(ctx,?next)=>{ctx.body?=?"my?name?is?liujianghong."})module.exports = router

每個路由文件里面都使用了一個路由前綴的設置,這樣方便分類。每個文件封裝了不同類型的路由,接下來要做的就是把這些路由進行整合。Koa源碼中有一個非常重要的實現是中間件的合并,其中就使用了koa-compose包,讀者可以返回《Koa開發:入門、進階與實戰》一書的第3章復習一下。路由的合并也會用到koa-compose來進行實現,代碼如下:

//?routers/index.jsconst?compose?=?require('koa-compose')const?glob?=?require('glob')const?{?resolve?}?=?require('path')registerRouter?=?()?=>?{let?routers?=?[];//?遞歸式獲取當前文件夾下所有的js文件glob.sync(resolve(__dirname,?'./',?'**/*.js'))//?排除index.js文件,因為這個文件不是具體的路由文件.filter(value?=>?(value.indexOf('index.js')?===?-1)).forEach(router?=>?{routers.push(require(router).routes())routers.push(require(router).allowedMethods())})return?compose(routers)}module.exports = registerRouter

這里可以使用koa-compose來對koa-router進行整合,是因為koa-router里面的routers方法和allowedMethods方法和我們平時用的中間件里面的回調是一樣的,讀者如果感興趣的話,可以看一下koa-router的源碼。最后實現一個簡單的server,即把整合后的路由引進來,代碼如下:

// app.jsconst Koa = require('koa')const registerRouter  = require('./routers')const app = new Koa()app.use(registerRouter())app.listen(4000, () => {console.log('server is running, port is 4000')})

運行app.js,我們在瀏覽器訪問http://127.0.0.1:4000/goods/getInfo,效果如圖1所示。

b4cd201cd449567eef1a6a91dbe50e10.png?圖1 訪問貨物路由運行結果

訪問http://127.0.0.1:4000/user/getInfo,效果如圖2所示。?

1efe3c9f39bb3a185b32defe0a256a18.png

圖2 訪問用戶路由運行結果


2、文件路由

根據文件路徑來匹配路由,也是實際的項目可能采取的一種方式,我們先了解一下什么是文件路由,比如,現在有這樣一個項目,組織結構如圖3所示。

d19150c17a3e651bdd0a76ff68ff1413.png?圖3 文件路由的項目結構

actions目錄下的內容就是匹配路由的,比如前端有一個GET請求http://127.0.0.1:4000/goods/getInfo,那么最終會匹配到actions目錄下goods/getInfo.js文件,最終會執行getInfo.js里面的邏輯。這么設計有以下幾點優勢:

●?依據項目中文件目錄就能了解本項目都有哪些路由,不用查看路由文件,非常方便。

●?用文件路徑來組織路由,對用戶非常友好,便于開發。

接下來我們詳細分析這種文件路由該如何實現。總共有兩個步驟:第一步,定義goods/getInfo.js和user/getInfo.js兩個文件內容,主要是定義一些屬性,包括請求的方法類型(GET、POST等)、執行的回調;第二步,把請求的path映射到對應的文件路徑上,當請求過來后,能夠執行對應的文件內容。接下來看代碼如何實現。

1)定義兩個文件內容

actions/goods/getInfo.js文件的定義代碼如下:

// actions/goods/getInfo.jsmodule.exports = {method: 'GET',  handler: (ctx) => {ctx.body = "this is koa book."}    }

actions/user/getInfo.js文件的定義代碼如下:

// actions/user/getInfo.js module.exports = {   method: 'GET',   handler: (ctx) => {     ctx.body = "my name is liujianghong."   }     }

兩個文件都定義了兩個屬性,一個是method,一個是handler。method指的是請求的類型,這里method的配置主要是為了映射到唯一請求,比如請求路徑都是/goods/getInfo,那方法類型既可以是GET請求,也可以POST請求,兩個請求是不一樣的。hander方法就是一個回調方法,用來處理相應的業務邏輯。

2)請求的path映射到對應的文件

首先請求的path可通過context對象來獲取,比較方便,主要問題是文件路徑如何處理。其實我們可以通過glob這個包來獲取所有的文件,然后對路徑再做相應的處理即可,代碼如下:

const glob = require('glob')const path = require('path')const Koa = require('koa')const app = new Koa()// actions的絕對路徑const basePath = path.resolve(__dirname, './actions')// 獲取actions目錄下所有的js文件,并返回其絕對路徑const filesList = glob.sync(path.resolve(__dirname, './actions', '**/*.js'))// 文件路由映射表let routerMap = {}filesList.forEach(item => {// 解構的方式獲取,當前文件導出對象中的method屬性和handler屬性const { method, handler } = require(item)// 獲取和actions目錄的相對路徑,例如:goods/getInfo.jsconst relative = path.relative(basePath, item)// 獲取文件后綴.jsconst extname = path.extname(item)// 剔除后綴.js,并在前面加一個"/",例如:/goods/getInfoconst fileRouter = '/' + relative.split(extname)[0]// 連接method,形成一個唯一請求,例如: _GET_/goods/getInfoconst key = '_' + method + '_' + fileRouter// 保存在路由表里routerMap[key] = handler})app.use(async (ctx, next) => {const { path, method } = ctx// 構建和文件路由匹配的形式:_GET_路由const key = '_' + method + '_' + path// 如果匹配到,就執行對應到handlerif (routerMap[key]) {routerMap[key](ctx)} else {ctx.body = 'no this router'}})app.listen(4000, () => {console.log('server is running, port is 4000')})

文件路由書寫起來比較優雅,并且可以做到高度可配置,這樣對每個請求可以實行個性化定制,我們在Koa實戰中也會使用這種方式來做路由,到時候詳細講述企業級別的BFF架構中文件路由該如何設計。

無論是通過中間件的路由分割還是通過文件的路由分割,都在一定程度上能夠優化路由的組織方式,方便后續的需求迭代。如果您想要了解更多有關Koa的高級應用,如用戶鑒權機制、數據存儲、進程管理等,推薦您詳細閱讀劉江虹老師的新作《Koa開發:入門、進階與實戰》。

作者介紹:劉江虹,字節跳動抖音電商前端架構師,目前主要負責業務架構中工程化等相關方向,擁有多年前端架構工作經驗。獨立開發過一款可對標Egg的BFF企業級框架,支撐公司線上服務超1000個,全棧前端技術專家,具有豐富的Node實戰經驗。著有暢銷書《React.js實戰》。

087db974613317529c80ac2a0b2ff792.png


?

抽獎規則:在留言區留言為什么想要這本書,隨機抽取「2位」理由充分 && 關注比較久 && 留言互動相對多的小伙伴。包郵送出本書。

另外為了鼓勵大家多寫源碼共讀筆記,我會在寫了5次及以上筆記的作者群里也抽獎送這本書。以后也會有更多福利傾斜。

開獎時間4月18日(周一)晚8點。中獎者在開獎后1天內與我取得聯系,否則視為放棄。我會在微信留言區回復中獎人。

中獎者開獎前必須是我的微信好友,且需是前端。羊毛黨繞路。

總之最終解釋權歸我。

記得掃碼加我微信 ruochuan12 , 參加源碼共讀。

600e42f49ccae7499b0308aa49106710.png

02bcea82e55a1bc245b4a192f57ce67a.gif

點擊閱讀全文購買

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/274740.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274740.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274740.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設計模式_設計

設計模式Thanks for my colleague WanChing‘s help to prepare this sharing article. E-Commerce app collects plentiful products from various brands. Each brand has its brand signature colors and public image. This article introduces how we made a single page …

動態切換css

方法一&#xff1a;給link一個id&#xff0c;直接獲取該DOM操作href <link rel"stylesheet" id"stylelink" type"text/css"/> <a href"#" οnclickjavascript:document.getElementById("stylelink").href "…

使用 GTD 優化自己的工作和生活

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

模仿不再受寵若驚

If you haven’t heard of the Jio-Zoom plagiarism clash, you’re probably living under a rock (which may not be a bad idea given the state of the world right now). The turf war between Jio Meet and Zoom began when the Indian telecom giant ripped off the Chi…

一個計算機愛好者的不完整回憶(二十八)關于計算機書籍

我只在大學階段在圖書館看了很多計算機方面的書&#xff0c;無論已經老得都殘破了還是最新出版的。前兩天又看到論壇中有關于計算機書籍特別是國內人士編寫或翻譯的計算機書籍的評論的文章&#xff0c;譚浩強老先生又毫無懸念的被牽連了進來。也發表一下自己的一些觀點吧。   …

Vue2剝絲抽繭-響應式系統 系列

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

word文本樣式代碼樣式_使用文本樣式表達創建真相來源

word文本樣式代碼樣式As of After Effects 17.0, you can use expressions to edit text styles in After Effects. Here’s why this would transform your workflow:從After Effects 17.0開始&#xff0c;您可以使用表達式在After Effects中編輯文本樣式。 這就是這將改變您的…

mvn備忘

創建web工程 mvn archetype:generate -DgroupIdcom.malangmedia -DartifactIdautoDeployToJetty -DarchetypeArtifactIdmaven-archetype-webapp -Dversion1.0 添加jetty插件 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.or…

前端框架源碼解讀之Vite

前端工具鏈十年盤點&#xff1a;https://mp.weixin.qq.com/s/FBxVpcdVobgJ9rGxRC2zfgWebpack、Rollup 、Esbuild、Vite ?webpack: 基于 JavaScript 開發的前端打包構建框架&#xff0c;通過依賴收集&#xff0c;模塊解析&#xff0c;生成 chunk&#xff0c;最終輸出生成的打包…

hp-ux_UX中的格式塔-或-為什么設計師如此討厭間距

hp-uxI’ve been lucky so far in my design career to have worked with engineers that seem genuinely interested in learning about design. Perhaps, as mentioned in the title, it’s more about them trying to figure out why it matters so much to us that there i…

很多人都不知道,其實博客園給我們博客開了二級域名

如題。一直都在郵件簽名里寫自己的博客地址為&#xff1a; http://www.cnblogs.com/datacool&#xff1b;直到有天突然發現使用&#xff1a;http://datacool.cnblogs.com也可以訪問。不知道的趕緊測試&#xff0c;后者明顯要酷很多啊。該不是我是最后一個知道的吧&#xff0c;知…

JavaScript 數組新增 4 個非破壞性方法!

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

自行車改裝電動車怎么樣_電動車聽起來應該是什么樣?

自行車改裝電動車怎么樣The sound of an all-electric car accelerating doesn’t have to sound like a standard combustion engine, It could sound like anything.全電動汽車加速的聲音不必聽起來像是標準的內燃機&#xff0c;它可以聽起來像任何東西。 These were the wor…

C++中的三種繼承public,protected,private(轉)

三種訪問權限 public:可以被任意實體訪問 protected:只允許子類及本類的成員函數訪問 private:只允許本類的成員函數訪問 三種繼承方式 public 繼承 protect 繼承 private 繼承 組合結果 基類中 繼承方式 子類中 public &#xff06; public繼承 > public public &#xff0…

如何碎片化時間學前端,了解前沿趨勢

我很開心在前端行業認識了一批優秀且樂于分享的朋友&#xff0c;他們的技術分享與職業觀點讓我獲益良多&#xff0c;推薦給大家一起關注。程序員成長指北Node.js 前端工程化 低代碼考拉小姐姐&#xff0c;一個有趣且樂于分享的人&#xff01;目前就職于某知名外企&#xff0c;負…

谷歌pay破解_Google Pay缺少Google聞名的一件事-UX案例研究

谷歌pay破解Disclaimer: The views expressed in the blog post is purely based on personal experience. It was not influenced by any external factor.When Google launched Tez (now Google Pay) in India during 2017, their primary goal was to design a simple payme…

進階高級前端,這位大前端架構師一定不能錯過

今天給大家介紹一位好朋友&#xff1a;這波能反殺&#xff1a;一位擁有十年工作經驗&#xff0c;對學習方法有獨到理解的資深大前端架構師。一、博客早在 2017 年初&#xff0c;波神在簡書平臺以《前端基礎進階》為名&#xff0c;更新了一系列優質文章&#xff0c;獲得大量認可…

memcached應用策略(轉)

memcached應用策略&#xff08;轉&#xff09;(2012-04-05 11:10:02) 轉載▼標簽&#xff1a; memcached 應用策略 it分類&#xff1a; linux_c memcached應用策略memcached 主要的作用是為減輕大訪問量對數據庫的沖擊&#xff0c;所以一般的邏輯是首先從memcached中讀取數據&a…

突然討厭做前端,討厭代碼_為什么用戶討厭重新設計

突然討厭做前端,討厭代碼重點 (Top highlight)The core of design thinking is to only design something that will bring value and fill the gap in consumer needs. Right? Why else would one design something that no one asked for? While that may be true to some …

那些年我面過的「六年經驗」的初級工程師

大家好&#xff0c;我是若川。持續組織了8個月源碼共讀活動&#xff0c;感興趣的可以 點此加我微信ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…