所有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,然后将它们附加到主文件中(添加到服务器对象)。您如何建议将其分开然后添加?
答案 0 :(得分:86)
您可以为用户路线(config/routes/user.js
)创建单独的文件:
module.exports = [
{ method: 'GET', path: '/users', handler: function () {} },
{ method: 'GET', path: '/users/{id}', handler: function () {} }
];
与购物车类似。然后在config/routes
(config/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
,您可以手动加载路径文件(例如cart
,user
),而不是手动加载它们:
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-directory或github网站上有完整的文档。
答案 3 :(得分:2)
或者您可以使用索引文件来加载所有路由 在目录
中/**
* 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!');
}
},
];
干杯