[英]Dynamically load versioned API routes into express.Router
我的路線位於./src/routes/api/v0/
,這是一個示例路線:
//src/routes/api/v0/dogs.js
import { Router } from 'express'
const router = Router()
router.get('/dogs', (req, res) => {
res.json({ message: 'List of all dogs' })
})
router.post('/dogs', (req, res) => {
res.json({ message: `Created a dog: ${req.body}` })
})
router.put('/dogs/:id', (req, res) => {
const { id } = req.params
res.json({ message: `Dog ${id} mutated into ${req.body}` })
})
router.delete('/dogs/:id', (req, res) => {
const { id } = req.params
res.json({ message: `Dog ${id} is gone` })
})
export { router as dogs }
假設還有一個類似的路由文件, cats.js
,為簡潔起見,這里省略了。 我正在從index.js
導出兩個模塊:
//src/routes/api/v0/index.js
export * from './cats'
export * from './dogs'
然后,我通過中介加載它們,如下所示:
//src/routes/api/index.js
import { Router } from 'express'
import { cats, dogs } from './v0'
const v0 = Router()
v0.use('/v0', cats)
v0.use('/v0', dogs)
export { v0 }
最后在server.js
加載它們:
//src/server.js
import v0 from './routes/api'
...
app.use('/api', v0)
...
有沒有辦法將單個路由模塊加載到express.Router
(我的src/routes/api/index.js
的v0
)而無需將每個模塊都傳遞給我? 就像是:
//src/routes/api/index.js
import { Router } from 'express'
import * as apiV0 from './v0'
const v0 = Router()
v0.use('/v0', magically feed it apiV0)
您可以使用fs
模塊讀取文件並導出其功能。 你可以在這里查看我的代碼。
我使用的__dirname
是模型目錄名。 那么你可以在你的應用程序啟動時使用這個神奇的一行要求。
import initFunction from 'src/routes'
import { Router } from 'express'
initFunction(Router()) // dont forget your express instance
initFunction
一種選擇是導出一組路由器,而不是為每個路由器命名。 然后,您可以遍歷該數組以通用方式將它們全部添加。 所以,而不是像你在這里做的那樣按名稱導入每個:
//src/routes/api/index.js
import { Router } from 'express'
import { cats, dogs } from './v0'
const v0 = Router()
v0.use('/v0', cats)
v0.use('/v0', dogs)
export { v0 }
您可以導出然后導入一組路由器,然后迭代該數組:
//src/routes/api/index.js
import { Router } from 'express'
import { allRouters } from './v0'
const v0 = Router()
for (const router of allRouters) {
v0.use('/v0', router)
}
export { v0 }
事實上,如果需要,您可以導出像現在這樣的單個命名路由器和路由器數組,然后導入代碼可以自由使用單個命名路由器或整個數組。
在 OP 編輯問題后添加此答案
您對顯示此問題的編輯:
//src/routes/api/v0/index.js
export * from './cats'
export * from './dogs'
為所有這些路由的任何類型的自動收集帶來一些復雜性。 ES6 的import
export
無法動態確定。 ES6 有意要求對導入和導出進行靜態分析。 因此,您不能在代碼循環中導入或導出。 這是對該主題的討論:
如果您使用的是require()
,那么您可以構建一個模塊,該模塊可以讀取配置文件並通過查看文件系統或讀取指定所有路由文件的配置文件來加載所有路由文件。 但是,您可以使用 ES6 import
和export
來做到這一點。 因此,據我所知,如果您要使用import
和export
,則必須手動指定導入。 通過在導出路由集合之前將它們放入數組中,您至少只需要進行一次手動聲明而不是兩次(這是對當前代碼的改進)。
這是手動導入它們,然后將它們導出到更容易處理的數組中:
//src/routes/api/v0/index.js
import {dogs} from './dogs'
import {cats} from './cats'
export const allRouters = [dogs, cats];
然后,您可以安裝它們:
//src/routes/api/index.js
import { Router } from 'express'
import { allRouters } from './v0'
const v0 = Router()
for (const router of allRouters) {
v0.use('/v0', router)
}
export { v0 }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.