Json 使用Express.js(node.js)进行动态路由的最佳方法

Json 使用Express.js(node.js)进行动态路由的最佳方法,json,node.js,content-management-system,express,router,Json,Node.js,Content Management System,Express,Router,我正在尝试使用express.js创建一个简单的CMS,动态创建路由。 它从如下所示的数据库中获取JSON: pagesfromdb = { home = { paths = ['/','/home','/koti'], render = 'home.ejs', fi_FI = {html='<h1>Hei maailma!</h1>'}, en_US = {html='<h1>Hello

我正在尝试使用express.js创建一个简单的CMS,动态创建路由。 它从如下所示的数据库中获取JSON:

pagesfromdb = {
    home = {
        paths = ['/','/home','/koti'],
        render = 'home.ejs',
        fi_FI = {html='<h1>Hei maailma!</h1>'},
        en_US = {html='<h1>Hello World!</h1>'}
    },
    about = {
        paths = ['/about','/tietoja'],
        render = 'general.ejs',
        fi_FI = {html='Tietoja'},
        en_US = {html='About Us'}
    }
}
现在一切正常。但问题是,每次用户修改内容和路径时,整个节点应用程序都需要重新启动。 我没有找到任何API调用来删除路由

有没有办法安全地删除app.get设置的旧路由?我应该这样做吗

有没有更好的方法来进行这种路由选择?我确实喜欢这种方法,因为它允许我使用内置函数,速度快并且支持正则表达式

我尝试用app.routes=nul删除整个app.routes,但没有任何效果,旧的路由仍然存在

有一件事确实消除了它们,那就是

delete app._router.map.get;
app._router.map.get = [];

但是这真的会删除它们吗?使用起来安全吗?这样,如果路由器不断被重新填充,我就不会劫持大量的ram了?

正如@supermova在评论中所说的,可以动态更新Express。另一个要考虑的架构是类似于经典的CMSs(例如WordPress)。在其他CMS中,所有请求都会转到同一个“回调”,并且在数据库中查找每个请求时,为该URL提供哪个页面

app.get('/*', function (req, res) {
   db.findPage({ slug: req.url}, function (err, pageData) {
       res.render('page-template', {
           pageContent: pageData.content,
           pageTitle: pageData.title
       });
   });
});

这种方法的结果是速度显著降低,但最终我认为这更合理。如果速度是一个巨大的问题,你可以设置一个缓存系统(比如Varnish),但是动态修改快速路线的方法会让人头疼。例如,如果您必须扩展到两个web服务器,该怎么办?如果服务器A收到“创建页面”请求,并且知道要更新其路由,那么如何保持它们的同步,但是服务器B呢?随着每个请求进入数据库,您将能够更好地横向扩展。

我会非常小心地尝试在运行时创建或销毁路由。虽然您可以自己更改数据结构,但我不相信这些数据结构是作为API记录的,因此如果升级Express,您可能会面临这种破坏的风险

如果为每个数据库对象创建新路由,这也可以作为内存约束,因为页面集可能会增长到谁知道有多大

像这样看。。。你不想要新的路线;您想将URL添加到现有路由。如果您要添加路由,这意味着您需要一些URL映射到某个不同的函数。但是您正在将每个URL映射到同一个函数。本质上,您只是通过副作用添加路线。您所关心的是,某个动态URL集映射到某个特定函数

您是否可以使用通配符将URL模式映射到特定函数,如

app.get('/pages/*', function(req, res) {
    var page = pagesfromdb[key];
    if (page != null) {
        res.render(page.render, page.language)
    }
    else {
        res.send(404);
    }
});

并在express层之外管理pagesfromdb映射。您可以使用直接数据库访问、缓存+数据库访问或基于计时器的刷新器,只要性能最好。

如前所述,可以动态添加路由。鉴于此功能,删除can也可以:

function deleteRoute(url) {
  for (var i = app.routes.get.length - 1; i >= 0; i--) {
    if (app.routes.get[i].path === "/" + url) {
      app.routes.get.splice(i, 1);
    }
  }
}
(偷自)


像这样更新路由确实会使你的应用程序“有状态”,如果你需要负载平衡,可能会导致问题。

AFAIk express会将所有路由保留在应用程序中。_router.map这样应该可以工作。是否有与渲染相关的缓存我应该担心。或者它们只是随应用程序一起删除。_router.map,因为它们就在它下面?在生产模式下,express缓存视图可以通过app.cache[viewname]访问缓存。我已经在使用Varnish,但在我看来,这不是解决问题的正确方法。。。与动态创建路由相比,当有大量页面时,这实际上非常慢。此方法的问题是我需要重新创建regexp功能。作为我第一个问题的后续问题。是否有任何方法可以在不使用任何包装器的情况下重新启动节点应用程序本身?这是可以做到的,但并不容易。您可以使用process.execPath和process.argv[1]启动自己。但为了让它工作,你必须首先断开任何网络套接字并解锁任何文件。。。一般资源清理。
function deleteRoute(url) {
  for (var i = app.routes.get.length - 1; i >= 0; i--) {
    if (app.routes.get[i].path === "/" + url) {
      app.routes.get.splice(i, 1);
    }
  }
}