Comment stocker les routes dans des fichiers séparés lors de L'utilisation de Hapi?
Tous les Hapi exemples (et similaire dans l'Express) montre les routes sont définies dans le fichier de démarrage:
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);
});
cependant, il n'est pas difficile d'imaginer la taille de ce fichier peut croître lors de la mise en œuvre de l'application de production avec une tonne de routes différentes. C'est pourquoi je voudrais ventiler les routes, les regrouper et les stocker dans des fichiers séparés, comme UserRoutes.js, CartRoutes.js et ensuite les joindre dans le fichier principal (Ajouter à l'objet server). Comment suggérez-vous de séparer cela et ensuite ajouter?
7 réponses
Vous pouvez créer un fichier séparé pour l'utilisateur routes (config/routes/user.js
):
module.exports = [
{ method: 'GET', path: '/users', handler: function () {} },
{ method: 'GET', path: '/users/{id}', handler: function () {} }
];
de même avec cart. Puis créer un fichier d'index config/routes
(config/routes/index.js
):
var cart = require('./cart');
var user = require('./user');
module.exports = [].concat(cart, user);
Vous pouvez ensuite charger ce fichier d'index dans le fichier principal et appel server.route()
:
var routes = require('./config/routes');
...
server.route(routes);
alternativement, pour config/routes/index.js
, au lieu d'ajouter les fichiers de route (par exemple cart
,user
) manuellement, vous pouvez les charger dynamiquement:
const fs = require('fs');
let routes = [];
fs.readdirSync(__dirname)
.filter(file => file != 'index.js')
.forEach(file => {
routes = routes.concat(require(`./${file}`))
});
module.exports = routes;
Vous devriez essayer de la Colle plugin: https://github.com/hapijs/glue. Il vous permet de modulariser votre application. Vous pouvez placer vos routes dans des sous-répertoires séparés et ensuite les inclure comme Hapi.js plugins. Vous pouvez également inclure d'autres plugins (Inert, Vision, Good) avec Glue ainsi que configurer votre application avec un objet manifest (ou fichier json).
Rapide exapmple:
le serveur.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/paquet.json:
{
"name": "IndexRoute",
"version": "1.0.0"
}
./ modules/index / home.js:
exports.register = function(req, reply) {
reply.view('home', { title: 'Awesome' });
});
regardez merveilleux article de Dave Stevens pour plus de détails et d'exemples.
Vous pouvez utiliser demande-hapiroutes pour faire partie de l'organisation et de chargement pour vous. (Je suis l'auteur donc je suis un peu partial, Je l'ai écrit pour rendre ma vie plus facile dans la gestion des itinéraires)
je suis un grand fan de demande-répertoire et je voulais un moyen de gérer mes itinéraires aussi facilement. Cela vous permet de mélanger et d'apparier des routes dans vos modules et modules dans des répertoires avec des routes.
vous pouvez alors faire quelque chose comme ce...
var routes = require('./routes');
server.route(routes.routes);
Puis dans votre répertoire, vous pouvez avoir un fichier de route comme...
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']
}
}];
Or, vous pouvez mélanger et faire correspondre en assignant à une propriété "routes" sur le module
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']
}
}];
Toujours bon d'avoir le choix. Il y a une documentation complète sur le github ou npmjs site pour.
ou vous pouvez utiliser un fichier d'index pour charger toutes les routes dans le répertoire
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;
autres fichiers dans le même répertoire comme:
module.exports = [
{
method: 'POST',
path: '/api/user',
config: {
}
},
{
method: 'PUT',
path: 'api/user/{userId}',
config: {
}
}
];
et que dans votre racine / index
const Routes = require('./src/routes');
/**
* Add all the routes
*/
for (var route in Routes) {
server.route(Routes[route]);
}
Intéressant de voir autant de solutions différentes, en voici une autre.
d'Expansion à la rescousse
pour mon dernier projet, j'ai décidé de globbing pour les fichiers avec un motif de nom particulier et ensuite de les requérir dans le serveur un par un.
importer les routes après avoir créé le server
objet
// 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.
// ...
Le glob motif **/*route*.js
va trouver tous les fichiers à l'intérieur et au-dessous du répertoire de travail courant spécifié avec un nom qui contient le mot route et se termine par le suffixe .js.
structure du fichier
Avec l'aide de l'expansion, nous avons un couplage lâche entre les server
l'objet et ses routes. Juste ajouter un nouvel itinéraire fichiers et ils seront inclus la prochaine fois que vous redémarrez votre serveur.
j'aime la structure de la route des fichiers en fonction de leur chemin et de les nommer avec leurs HTTP-méthode, comme suit:
server.js
routes/
users/
get-route.js
patch-route.js
put-route.js
articles/
get-route.js
patch-route.js
put-route.js
exemple de fichier de route routes/users/get-route.js
module.exports = {
method: 'GET',
path: '/users',
config: {
description: 'Fetch users',
// ...
},
handler: function (request, reply) {
// ...
}
};
conclusion
Globbing and iterating over files n'est pas un processus particulièrement rapide, donc une couche de mise en cache peut être intéressante à étudier dans les constructions de production en fonction de vos circonstances.
hapi-auto-route plugin! Il est très simple d'utiliser et de permettre le préfixe dans votre chemin.
je sais que c'est déjà approuvé. Je pose ma solution au cas où quelqu'un voudrait une solution rapide et nouvelle à Hapi.
J'ai aussi inclus des NPM pour que les débutants puissent voir comment utiliser le server.register
avec plugin multiple dans le cas (good
+ hapi-auto-route
)
Installé quelques packages 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);
});
});
Dans votre 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!');
}
},
];
exécuter: node server.js
Cheers