gpt4 book ai didi

javascript - ExpressJS : Adding routes dynamically at runtime

转载 作者:行者123 更新时间:2023-12-05 00:35:33 24 4
gpt4 key购买 nike

我希望能够在运行时添加新路由,而无需使用 NodeJS 和 ExpressJS 重新启动服务器。我在这篇文章中做了一个类似的方法:https://alexanderzeitler.com/articles/expressjs-dynamic-runtime-routing/从技术上讲,我同样可以在文章中在运行时添加新文件和逻辑,但问题是当没有匹配 api 路由时,我会发送一个 404 JSON 响应(因为它应该是)。我认为问题我所拥有的是我的动态创建的路由永远不会到达,因为静态路由优先于动态创建的路由。这意味着创建的路由将在错误处理后挂载,因此永远不会到达。我的代码在 app.js

...

// Routes
app.use('/api/products', productRoutes);
app.use('/api/users', userRoutes);

...

/* This is where the dynamically created routes should be mounted */

// Error handling
app.use((req, res, next) => {
const err = new Error('Not found');
err.status = 404;
next(err);
});

app.use((err, req, res, next) => {
res.status(err.status || 500).json({error: {message: err.message}});
});

/* This is where the dynamic routes are mounted */

module.exports = app;

当我注释掉错误处理时,我可以访问在运行时创建的路由,而通过错误处理,我只能在服务器重新启动后访问动态创建的路由,这是我想避免的。问题无法通过查询参数解决,因为动态添加的路由在逻辑、模型属性、http 方法/动词和 API 端点上有所不同。例如GET/POST/api/{endpoint}GET/POST/api/foo/{endpoint}GET/PUT/DELETE/api/foo/bar/{endpoint}/:id
我认为我基本上需要:1)在错误处理之前找到一种方法来安装动态创建的路由 - 我目前停留在 or2)修改路由堆栈 - 我读过这是不切实际的、缓慢的、不好的做法和容易出错3) 找到替代解决方案我希望有人能帮助我。提前致谢 编辑 这是创建新路线的代码。相关端点是 POST 方法中的/api/databases/

const Database = require('../models/database');
const controller = require('./template/controller');
const creation = require('../Creation');

...

exports.createOne = (req, res, next) => {
if (!creation.findFileInDirectory(`./backend/api/models/${req.body.name.singular}.js`) ||
!creation.findFileInDirectory(`./backend/api/controllers/${req.body.name.singular}.js`) ||
!creation.findFileInDirectory(`./backend/api/routes/${req.body.name.singular}.js`)) {
controller.createOne(req, res, next, Database, {
modelName: 'database',
}, () => {
//creation.createEndpoint(req.body.name, req.body.data, req.body.auth);
creation.createEndpoint(req.body.name, req.body, req.body.auth);
});
} else {
res.status(422).json({message: 'Endpoint exists already'});
}
}

...

片段中的 Controller 只是一个模块化 Controller 文件,它处理我对不同模型的所有端点的所有 CRUD 操作。每条路由都被拆分为模型、 Controller 和路由,以分离和更好地维护它们的逻辑。在 POST 方法中,我首先检查要创建的端点是否已经存在。如果是这样,我会以 422 响应,表明端点已经存在。如果它不存在,我在数据库端点中创建一个我的模块化 Controller 的条目,并为应该创建的端点创建一个模型、 Controller 和路由。创建逻辑如下:

const createEndpoint = (name, data, auth) => {
createFile(`./backend/api/models/${name.singular}.js`, model.createModel(capitalize(name.singular), data), () => {
createFile(`./backend/api/controllers/${name.singular}.js`, controller.createController({singular: capitalize(name.singular), plural: name.plural}, data.data), () => {
createFile(`./backend/api/routes/${name.singular}.js`, route.createRoute({singular: capitalize(name.singular), plural: name.plural}, auth), () => {
const app = require('../../app');
mountEndpoints(name.singular, app);
});
});
});
};

在这里,我基本上将数据从 POST 方法传递到异步创建的模型、 Controller 和路由文件。创建所有文件后,我将端点路由安装到应用程序。挂载路由的逻辑是:

const mountEndpoints = (path, app) => {
const module = require(`../routes/${path}`);
app.use(`/api/${module.plural ? `${module.plural}` : `${path}s`}`, module);
}

创建的路由可能如下所示:

const express   = require('express');
const router = express.Router();
const checkAuth = require('../middleware/check-auth');

const ProductController = require('../controllers/product');

router.route('/')
.get(ProductController.getAll)
.post(checkAuth, ProductController.createOne);

router.route('/:id')
.get(ProductController.getOne)
.patch(checkAuth, ProductController.patchOne)
.delete(checkAuth, ProductController.deleteOne);

module.exports = router;
module.exports.plural = 'products';

checkAuth 包含一些用于授权/身份验证的逻辑。该代码几乎可以完成我想要它做的事情,除了我不知道如何在错误处理之前处理路由的定位。

最佳答案

快速路线将按创建顺序处理。
app 之后的特定位置添加路线定义您可以创建一个占位符路由器并将路由附加到那里而不是 app本身。
Express 不支持在定义路由后删除,但您可以 replace an entire router .
创建一个快速路由器实例(如果需要,甚至可以创建另一个 app)来挂载动态端点。每当您想要更改路由时重新定义路由器(除了添加到路由器堆栈的末尾,这是由 express 支持的)。

// Routes
app.use('/api/products', productRoutes);
app.use('/api/users', userRoutes);

let dynamicApiRouter = null

export function setupDynamicRouter(config) {
dynamicApiRouter = new express.Router()
// Add routes to dynamicApiRouter from `config`
dynamicApiRouter[config.method](config.path, config.handler)
}

app.use('/api', (req, res, next) => dynamicApiRouter(req, res, next))

// Error handling
app.use((req, res, next) => {
const err = new Error('Not found');
err.status = 404;
next(err);
});

app.use((err, req, res, next) => {
res.status(err.status || 500).json({error: {message: err.message}});
});
然后,当您挂载一个新端点时,将路由器传入并删除 /api路径前缀,因为它现在在父 app 中的路由器外部处理.
const mountEndpoints = (path, router) => {
const module = require(`../routes/${path}`);
router.use(`/${module.plural ? `${module.plural}` : `${path}s`}`, module);
}

关于javascript - ExpressJS : Adding routes dynamically at runtime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63199945/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com