使用Hapi时如何在单独的文件中存储路由?

时间:2015-01-04 14:40:53

标签: node.js routes hapijs

所有Hapi示例(以及Express中的类似示例)都显示路由在起始文件中定义:

var Hapi = require('hapi');

var server = new Hapi.Server();
server.connection({ port: 8000 });

server.route({
  method: 'GET',
  path: '/',
  handler: function (request, reply) {
    reply('Hello, world!');
  }
});

server.route({
  method: 'GET',
  path: '/{name}',
  handler: function (request, reply) {
    reply('Hello, ' + encodeURIComponent(request.params.name) + '!');
  }
});

server.start(function () {
  console.log('Server running at:', server.info.uri);
});

但是,在实现具有大量不同路由的生产应用程序时,不难想象这个文件有多大。因此,我想分解路由,将它们分组并存储在单独的文件中,如UserRoutes.js,CartRoutes.js,然后将它们附加到主文件中(添加到服务器对象)。您如何建议将其分开然后添加?

7 个答案:

答案 0 :(得分:86)

您可以为用户路线(config/routes/user.js)创建单独的文件:

module.exports = [
    { method: 'GET', path: '/users', handler: function () {} },
    { method: 'GET', path: '/users/{id}', handler: function () {} }
];

与购物车类似。然后在config/routesconfig/routes/index.js)中创建一个索引文件:

var cart = require('./cart');
var user = require('./user');

module.exports = [].concat(cart, user);

然后,您可以在主文件中加载此索引文件并调用server.route()

var routes = require('./config/routes');

...

server.route(routes);

或者,对于config/routes/index.js,您可以手动加载路径文件(例如cartuser),而不是手动加载它们:

const fs = require('fs');

let routes = [];

fs.readdirSync(__dirname)
  .filter(file => file != 'index.js')
  .forEach(file => {
    routes = routes.concat(require(`./${file}`))
  });

module.exports = routes;

答案 1 :(得分:14)

您应该尝试使用Glue插件:https://github.com/hapijs/glue。它允许您模块化您的应用程序。您可以将路由放在单独的子目录中,然后将它们包含在Hapi.js插件中。您还可以使用Glue包含其他插件(Inert,Vision,Good)以及使用清单对象(或json文件)配置应用程序。

快速解释:

<强> server.js:

var Hapi = require('hapi');
var Glue = require('glue');

var manifest = {
    connections: [{
        port: 8080
    }],
    plugins: [
        { inert: [{}] },
        { vision: [{}] },
        { './index': null },
        {
            './api': [{
                routes: {
                    prefix: '/api/v1'
                }
            }]
        }
    ]
};


var options = {
    relativeTo: __dirname + '/modules'
};

Glue.compose(manifest, options, function (err, server) {
    server.start(function(err) {
        console.log('Server running at: %s://%s:%s', server.info.protocol, server.info.address, server.info.port);
    });
});

<强> ./模块/索引/ index.js:

exports.register = function(server, options, next) {
    server.route({
        method: 'GET',
        path: '/',
        handler: require('./home')
    });
});

exports.register.attributes = {
    pkg: require('./package.json')
};

<强> ./模块/索引/的package.json:

{
    "name": "IndexRoute",
    "version": "1.0.0"
}

<强> ./模块/索引/ home.js:

exports.register = function(req, reply) {
    reply.view('home', { title: 'Awesome' });
});

请查看Dave Stevens撰写的this精彩文章,了解更多详情和示例。

答案 2 :(得分:6)

您可以使用here为您执行某些组织和加载。 (我是作者所以我有点偏颇,我写这篇文章是为了让我的生活更轻松地管理路线)

我是require-hapiroutes的忠实粉丝,并希望能够轻松管理我的路线。这使您可以在路径中的模块和模块中混合和匹配路径。

然后你可以做这样的事情......

var routes = require('./routes');
server.route(routes.routes);

然后在您的目录中,您可以拥有一个路径文件,如...

module.exports = [
{
  method : 'GET',
  path : '/route1',
  handler : routeHandler1,
  config : {
    description: 'my route description',
    notes: 'Important stuff to know about this route',
    tags : ['app']
  }
},
{
  method : 'GET',
  path : '/route2',
  handler : routeHandler2,
  config : {
    description: 'my route description',
    notes: 'Important stuff to know about this route',
    tags : ['app']
  }
}];

或者,您可以通过分配&#34;路线&#34;来混合和匹配。模块上的财产

module.exports.routes = [
{
  method : 'GET',
  path : '/route1',
  handler : routeHandler1,
  config : {
    description: 'my route description',
    notes: 'Important stuff to know about this route',
    tags : ['app']
  }
},
{
  method : 'GET',
  path : '/route2',
  handler : routeHandler2,
  config : {
    description: 'my route description',
    notes: 'Important stuff to know about this route',
    tags : ['app']
  }
}];

总是,很高兴有选择权。 require-directorygithub网站上有完整的文档。

答案 3 :(得分:2)

或者您可以使用索引文件来加载所有路由 在目录

index.js

/**
 * Module dependencies.
 */
const fs = require('fs');
const path = require('path');
const basename  = path.basename(__filename);

const routes = fs.readdirSync(__dirname)
.filter((file) => {
    return (file.indexOf('.') !== 0) && (file !== basename);
})
.map((file) => {
    return require(path.join(__dirname, file));
});

module.exports = routes;

同一目录中的其他文件,如:

module.exports =  [
    {
        method: 'POST',
        path:  '/api/user',
        config: {

        }
    },
    {
        method: 'PUT',
        path:  'api/user/{userId}',
        config: {

        }
    }
];

而不是你的root / index

const Routes = require('./src/routes');
/**
* Add all the routes
*/
for (var route in Routes) {
    server.route(Routes[route]);
}

答案 4 :(得分:0)

有兴趣看到这么多不同的解决方案,这是另一个解决方案。

全力以赴救援

对于我的最新项目,我决定对具有特定名称模式的文件进行通配,然后逐个进入服务器。

创建server对象

后导入路径
// Construct and setup the server object.
// ...

// Require routes.
Glob.sync('**/*route*.js', { cwd: __dirname }).forEach(function (ith) {
    const route = require('./' + ith);
    if (route.hasOwnProperty('method') && route.hasOwnProperty('path')) {
        console.log('Adding route:', route.method, route.path);
        server.route(route);
    }
});

// Start the server.
// ...

glob模式**/*route*.js将查找指定当前工作目录内和下的所有文件,其名称包含单词 route ,并以后缀 .js结尾

文件结构

在globbing的帮助下,server对象与其路径之间存在松耦合。只需添加新的路由文件,下次重新启动服务器时就会包含这些文件。

我喜欢根据路径构建路径文件并使用HTTP方法命名它们,如下所示:

server.js
routes/
    users/
        get-route.js
        patch-route.js
        put-route.js
    articles/
        get-route.js
        patch-route.js
        put-route.js

示例路由文件routes/users/get-route.js

module.exports = {
    method: 'GET',
    path: '/users',
    config: {
        description: 'Fetch users',
        // ...
    },
    handler: function (request, reply) {
        // ...
    }
};

最后的想法

对文件进行遍历和迭代并不是一个特别快速的过程,因此根据您的具体情况,缓存层可能值得在生产版本中进行调查。

答案 5 :(得分:0)

试用hapi-auto-route插件!它的使用非常简单,并允许在您的路径路径中使用前缀。

答案 6 :(得分:0)

我知道这已经被批准了。我放下了我的解决方案,以防有人想要快速修复和Hapi新手。

我也包含了一些NPM,因此Newbees可以看到如何在server.register + good

的情

安装了一些npm包:

hapi-auto-route

npm i -S hapi-auto-route npm i -S good-console npm i -S good // server.js 'use strict'; const Hapi = require('hapi'); const Good = require('good'); const AutoRoute = require('hapi-auto-route'); const server = new Hapi.Server(); server.connection( { routes: { cors: true }, port: 3000, host: 'localhost', labels: ['web'] } ); server.register([{ register: Good, options: { reporters: { console: [{ module: 'good-squeeze', name: 'Squeeze', args: [{ response: '*', log: '*' }] }, { module: 'good-console' }, 'stdout'] } } }, { register: AutoRoute, options: {} }], (err) => { if (err) { throw err; // something bad happened loading the plugin } server.start((err) => { if (err) { throw err; } server.log('info', 'Server running at: ' + server.info.uri); }); });

routes/user.js

现在运行:module.exports = [ { method: 'GET', path: '/', handler: (request, reply) => { reply('Hello, world!'); } }, { method: 'GET', path: '/another', handler: (request, reply) => { reply('Hello, world again!'); } }, ];

干杯