簡體   English   中英

將版本化 API 路由動態加載到 express.Router

[英]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.jsv0 )而無需將每個模塊都傳遞給我? 就像是:

//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 有意要求對導入和導出進行靜態分析。 因此,您不能在代碼循環中導入或導出。 這是對該主題的討論:

我可以使用循環來最小化 ES6 導入語句嗎?

如果您使用的是require() ,那么您可以構建一個模塊,該模塊可以讀取配置文件並通過查看文件系統或讀取指定所有路由文件的配置文件來加載所有路由文件。 但是,您可以使用 ES6 importexport來做到這一點。 因此,據我所知,如果您要使用importexport ,則必須手動指定導入。 通過在導出路由集合之前將它們放入數組中,您至少只需要進行一次手動聲明而不是兩次(這是對當前代碼的改進)。

這是手動導入它們,然后將它們導出到更容易處理的數組中:

//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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM