すべての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などの個別のファイルに保存してから、メインファイルに追加します(サーバーオブジェクトに追加します)。それを分離してから追加するにはどうすればよいですか?
ユーザールート用に別のファイルを作成できます(_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;
_
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);
});
});
./ modules/index/index.js:
exports.register = function(server, options, next) {
server.route({
method: 'GET',
path: '/',
handler: require('./home')
});
});
exports.register.attributes = {
pkg: require('./package.json')
};
./ modules/index/package.json:
{
"name": "IndexRoute",
"version": "1.0.0"
}
./ modules/index/home.js:
exports.register = function(req, reply) {
reply.view('home', { title: 'Awesome' });
});
詳細と例については、Dave Stevensによる this すばらしい記事をご覧ください。
require-hapiroutes を使用して、組織の一部とロードを行うことができます。 (私は著者なので、少し偏見があります。ルートを管理する上で私の生活を楽にするために書きました)
私は require-directory の大ファンであり、同様に簡単にルートを管理する方法を望んでいました。これにより、モジュール内のルートと、ディレクトリ内のモジュールをルートと組み合わせて一致させることができます。
その後、このようなことを行うことができます...
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']
}
}];
または、モジュールの「ルート」プロパティに割り当てることで、組み合わせて一致させることができます
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']
}
}];
または、インデックスファイルを使用して、ディレクトリ内のすべてのルートをロードできます。
/**
* 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: {
}
}
];
そしてあなたのルート/インデックスよりも
const Routes = require('./src/routes');
/**
* Add all the routes
*/
for (var route in Routes) {
server.route(Routes[route]);
}
hapi-auto-route プラグインを試してください!ルートパスにプレフィックスを使用して許可するのは非常に簡単です。
非常に多くの異なるソリューションを見るのが面白いので、別のソリューションを紹介します。
私の最新のプロジェクトでは、特定の名前パターンのファイルをグロビングし、それらを1つずつサーバーに要求することに決めました。
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
は、指定された現在の作業ディレクトリ内およびその下に、Word routeが含まれ、末尾が。jsで終わるすべてのファイルを検索します。
グロビングの助けを借りて、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) {
// ...
}
};
ファイルのグロビングと反復は特に高速なプロセスではないため、状況に応じて、キャッシングレイヤーを運用ビルドで調査する価値があります。
私はこれがすでに承認されていることを知っています。誰かが迅速な修正を希望し、Hapiを初めて使用する場合に備えて、ソリューションを書き留めました。
また、Newbeeがserver.register
複数のプラグインの場合(good
+ hapi-auto-route
)
いくつかのnpmパッケージをインストールしました:
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!');
}
},
];
実行:node server.js
乾杯