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?

41
demandé sur Gergo Erdosi 2015-01-04 17:40:53

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;
77
répondu Gergo Erdosi 2017-08-16 09:48:22

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.

14
répondu coquin 2015-10-29 07:33:30

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.

6
répondu Brian ONeil 2015-10-19 15:54:52

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]);
}
1
répondu Whisher 2015-10-20 11:25:45

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.

0
répondu Fredric 2016-03-25 10:05:21

hapi-auto-route plugin! Il est très simple d'utiliser et de permettre le préfixe dans votre chemin.

0
répondu sitrakay 2017-04-04 08:00:34

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

0
répondu Mr H 2017-08-17 04:43:06