Comment stocker des itinéraires dans des fichiers séparés lors de l’utilisation de Hapi?

Tous les exemples Hapi (et similaires dans Express) montrent que les itinéraires sont définis dans le fichier de départ:

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 l’ampleur de la croissance de ce fichier lors de la mise en œuvre d’une application de production avec une multitude de routes différentes. Par conséquent, je voudrais décomposer les routes, les regrouper et les stocker dans des fichiers distincts, tels que UserRoutes.js, CartRoutes.js, puis les joindre au fichier principal (ajout à un object serveur). Comment suggéreriez-vous de séparer cela puis d’append?

Vous pouvez créer un fichier distinct pour les itinéraires utilisateur ( config/routes/user.js ):

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

De même avec un chariot. Créez ensuite un fichier d’index dans 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 appeler server.route() :

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

Alternativement, pour config/routes/index.js , au lieu d’append manuellement les fichiers de routage (ex: cart , user ), vous pouvez les charger dynamicment:

 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 le plugin Glue: https://github.com/hapijs/glue . Il vous permet de modulariser votre application. Vous pouvez placer vos itinéraires dans des sous-répertoires distincts, puis les inclure en tant que plug-ins Hapi.js. Vous pouvez également inclure d’autres plugins (Inert, Vision, Good) avec Glue, ainsi que configurer votre application avec un object manifeste (ou un fichier json).

Exapmple rapide:

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.atsortingbutes = { 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' }); }); 

Jetez un oeil à cet article merveilleux de Dave Stevens pour plus de détails et d’exemples.

Vous pouvez utiliser require-hapiroutes pour faire une partie de l’organisation et du chargement pour vous. (Je suis l’auteur donc je suis un peu partial, je l’ai écrit pour me faciliter la vie dans la gestion des routes)

Je suis un grand fan de require-directory et je voulais un moyen de gérer mes routes tout aussi facilement. Cela vous permet de combiner des itinéraires dans vos modules et modules dans des répertoires avec des itinéraires.

Vous pouvez alors faire quelque chose comme ça …

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

Ensuite, dans votre répertoire, vous pourriez 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'] } }]; 

Ou, vous pouvez combiner et associer 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 des options. Il existe une documentation complète sur le site github ou npmjs .

ou vous pouvez utiliser un fichier d’index pour charger tous les itinéraires 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.

Glotting à la rescousse

Pour mon dernier projet, je me suis mis à la globalisation des fichiers avec un modèle de nom particulier et à les exiger dans le serveur un par un.

Importer des routes après avoir créé l’object 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. // ... 

Le modèle glob **/*route*.js trouvera tous les fichiers dans et sous le répertoire de travail en cours avec un nom qui contient le mot route et se termine par le suffixe .js .

Structure de fichier

Avec l’aide de la globalisation, nous avons un couplage lâche entre l’object server et ses routes. Ajoutez simplement de nouveaux fichiers de route et ils seront inclus lors du prochain redémarrage de votre serveur.

J’aime structurer les fichiers de route en fonction de leur chemin et en les nommant avec leur méthode HTTP, comme ceci:

 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 routes/users/get-route.js

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

Dernières pensées

Globaliser et itérer sur des fichiers n’est pas un processus particulièrement rapide. Par conséquent, une couche de mise en cache peut être utile dans les versions de production en fonction de votre situation.

Essayez le plugin hapi-auto-route ! C’est très simple à utiliser et à autoriser le préfixe dans votre chemin.

Je sais que c’est déjà approuvé. J’ai mis ma solution au cas où quelqu’un voudrait une solution rapide et une nouvelle pour Hapi.

J’ai aussi inclus certains NPM aussi Newbees peut voir comment utiliser le server.register avec plusieurs plugins dans le cas ( good + hapi-auto-route )

Installation de certains packages npm:

 npm i -S hapi-auto-route npm i -S good-console npm i -S good // server.js 'use ssortingct'; 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 vos 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!'); } }, ]; 

Maintenant, lancez: node server.js

À votre santé