【问题标题】:Dynamic routing depending on version number动态路由取决于版本号
【发布时间】:2013-02-19 06:56:41
【问题描述】:

我正在使用 Express3 框架在 node.js 上开发一个 web api,我希望我的路由看起来像 /v0.1/function

理想情况下,路由应该通过查看 url 中给出的主要和次要版本号来自动加载指定的版本模块。到目前为止,我的方法是:

app.use('/v:major.:minor', function(req) {
    return require('./v' + req.params.major + '.' +
        req.params.minor);
});

在我的./v0.1/index.js:

module.exports = function() {
    var express = require('express'),
        app = express();
    app.get('/test', function(req, res) {
        res.json({ success: true });
    });
    return app;
}();

如果我现在打电话给/v0.1/test,它与路线(404)不匹配,但app.get('/v:major.:minor', function(req, res) { /* ... */ }); 工作正常。

我怎样才能做到这一点?

【问题讨论】:

    标签: node.js routing express


    【解决方案1】:

    我想你想要app.all (http://expressjs.com/api.html#app.all)

    这将使所有 HTTP 动词都可以访问,并且变量路由仍然有效。

    我测试了它,它似乎可以工作。

    根据评论编辑

    app.all('/v:major.:minor/:endpoint', function(req, res, next) {
        var version_handler = require('./v' + req.params.major + '.' + req.params.minor);
        if (!req.params.endpoint in version_handler) // endpoint_isn't supported at this version, 404
        version_handler[req.params.endpoint](req, res, next);
    });
    

    【讨论】:

    • 你能提供你的测试吗?我可以匹配路由并使用app.all('/:param/*', function(req) {}) 之类的参数获取参数,但是我如何加载我想要的模块并让它从那里处理路由?我需要能够在回调函数中定义更多路由。
    • 你不能为每个你想要的端点做app.all('/v:major.:minor/endpoint', function(req, res, next) { require('./v' + req.params.major + '.' + req.params.minor).endpoint(req, res, next) })吗?
    • 问题是随着新功能的添加或旧功能的删除,不同的版本可能具有不同的端点。我想我可以导出一个端点数组并对其进行迭代-如果无法实现我想要的,那是我没有考虑过的解决方案
    • 我编辑了答案以提供更通用的处理程序。然后您的 module.exports 只是一个对象,其中键是端点名称,值是该端点的处理程序。您还可以在端点变量中进行一些有趣的更改以提供嵌套端点,即 /v1.2/nested/endpoint
    • 但是你应该如何处理额外的参数呢? F.x. localhost/v1.0/articleslocalhost/v1.0/article/3 与单个表达式 /v:major.:minor/:endpoint
    【解决方案2】:

    您必须使用app.param()。来自express API 中的示例:

    app.param('id', /^\d+$/);
    
    app.get('/user/:id', function(req, res){
      res.send('user ' + req.params.id);
    });
    

    您必须在 URL 中为您的参数提供正则表达式,因为主要和次要都是非负整数 /^\d+$/ 应该适合您。

    【讨论】:

    • 您给出的示例的一半取自验证 url 参数的方法;我在使用 app.use 时遇到了问题。使用不采取任何措施。我需要根据 url 参数动态加载 vX.Y 模块,但我看不出这对我有什么帮助。能详细点吗?
    【解决方案3】:

    我发现最简单的方法是链接自定义中间件:

    类似这样的:

    app.use('/api/:version', function (req, res, next) {
        console.log('The version name is : ', req.params.version)
        req.version=req.params.version; //use this inside api router
        next() // pass control to the next handler
    },api);
    

    api 是您的路由器对象

    【讨论】:

      猜你喜欢
      • 2014-12-31
      • 1970-01-01
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多