Динамически загружать версионные маршруты API в express .Router - PullRequest
0 голосов
/ 09 марта 2020

Мои маршруты живут в ./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 (v0 в моем src/routes/api/index.js), не передавая каждый отдельный модуль моей руке? Что-то вроде:

//src/routes/api/index.js
import { Router } from 'express'
import * as apiV0 from './v0'

const v0 = Router()

v0.use('/v0', magically feed it apiV0)

Ответы [ 2 ]

0 голосов
/ 09 марта 2020

Одним из вариантов будет экспорт массива маршрутизаторов, а не именование каждого из них. Затем вы можете просто перебрать этот массив, чтобы добавить их все в общем виде c. Таким образом, вместо импорта каждого по имени, как вы делаете здесь:

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

создает некоторые сложности для любого вида автоматов c коллекция все эти маршруты. ES6 import и export не могут быть определены динамически. Специально для ES6 необходим статический анализ импорта и экспорта. Таким образом, вы не можете импортировать или экспортировать в oop кода. Вот обсуждение этой топи c:

Могу ли я использовать циклы для минимизации операторов импорта 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 }
0 голосов
/ 09 марта 2020

Вы можете использовать модуль fs для чтения файла и экспорта его функций. Вы можете посмотреть мой код здесь .

__dirname, который я использую, это dirname модели. тогда вы можете использовать эту магию c одна строка требуется при запуске вашего приложения.

import initFunction from 'src/routes'
import { Router } from 'express'

initFunction(Router()) // dont forget your express instance

initFunction
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...