it-swarm.com.de

Wie speichere ich Routen in separaten Dateien, wenn ich Hapi verwende?

Alle Hapi-Beispiele (und ähnliche in Express) zeigen, dass Routen in der Startdatei definiert sind:

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);
});

Es ist jedoch nicht schwer abzubilden, wie groß diese Datei werden kann, wenn eine Produktionsanwendung mit einer Vielzahl unterschiedlicher Routen implementiert wird. Daher möchte ich Routen aufschlüsseln, gruppieren und in separaten Dateien wie UserRoutes.js, CartRoutes.js speichern und diese dann in der Hauptdatei anhängen (zum Serverobjekt hinzufügen). Wie würden Sie vorschlagen, das zu trennen und dann hinzuzufügen?

47
Centurion

Sie können eine separate Datei für Benutzerrouten erstellen (config/routes/user.js):

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

Ähnliches gilt für Einkaufswagen. Dann erstelle eine Indexdatei in config/routes (config/routes/index.js):

var cart = require('./cart');
var user = require('./user');

module.exports = [].concat(cart, user);

Sie können diese Indexdatei dann in die Hauptdatei laden und server.route() aufrufen:

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

...

server.route(routes);

Alternativ können Sie für config/routes/index.js Die Routendateien (z. B. cart, user) auch dynamisch laden, anstatt sie manuell hinzuzufügen:

const fs = require('fs');

let routes = [];

fs.readdirSync(__dirname)
  .filter(file => file != 'index.js')
  .forEach(file => {
    routes = routes.concat(require(`./${file}`))
  });

module.exports = routes;
87
Gergo Erdosi

Sie sollten das Glue-Plugin ausprobieren: https://github.com/hapijs/glue . Damit können Sie Ihre Anwendung modularisieren. Sie können Ihre Routen in separaten Unterverzeichnissen ablegen und diese dann als Hapi.js-Plugins einbinden. Sie können auch andere Plugins (Inert, Vision, Good) in Glue einbinden und Ihre Anwendung mit einem Manifest-Objekt (oder einer JSON-Datei) konfigurieren.

Schnelles Beispiel:

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' });
});

Schauen Sie sich this wundervollen Artikel von Dave Stevens für weitere Details und Beispiele an.

15
coquin

Sie können require-hapiroutes verwenden, um einen Teil der Organisation und des Ladens für Sie durchzuführen. (Ich bin der Autor, daher bin ich ein bisschen voreingenommen. Ich habe es geschrieben, um mein Leben beim Verwalten von Routen zu vereinfachen.)

Ich bin ein großer Fan von require-directory und wollte eine Möglichkeit, meine Routen genauso einfach zu verwalten. Auf diese Weise können Sie Routen in Ihren Modulen und Module in Verzeichnissen mit Routen mischen und zuordnen.

Sie können dann so etwas tun ...

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

Dann könnten Sie in Ihrem Verzeichnis eine Routendatei haben wie ...

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']
  }
}];

Sie können auch mischen und abgleichen, indem Sie eine "Routen" -Eigenschaft im Modul zuweisen

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']
  }
}];

Immer gut, Optionen zu haben. Es gibt eine vollständige Dokumentation auf der github oder npmjs Seite.

6
Brian ONeil

oder Sie können eine Indexdatei verwenden, um alle Routen im Verzeichnis zu laden

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;

andere Dateien im selben Verzeichnis wie:

module.exports =  [
    {
        method: 'POST',
        path:  '/api/user',
        config: {

        }
    },
    {
        method: 'PUT',
        path:  'api/user/{userId}',
        config: {

        }
    }
];

und dann in deinem root/index

const Routes = require('./src/routes');
/**
* Add all the routes
*/
for (var route in Routes) {
    server.route(Routes[route]);
}
2
Whisher

Versuchen Sie Hapi-Auto-Route Plugin! Es ist sehr einfach, Präfix in Ihrem Routenpfad zu verwenden und zuzulassen.

0
sitrakay

Interessant, so viele verschiedene Lösungen zu sehen, hier ist eine andere.

Zur Rettung flitzen

Bei meinem letzten Projekt habe ich mich entschlossen, nach Dateien mit einem bestimmten Namensmuster zu suchen und sie dann einzeln auf dem Server zu speichern.

Importieren Sie Routen, nachdem Sie das Objekt server erstellt haben

// 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.
// ...

Das Glob-Muster **/*route*.js findet alle Dateien innerhalb und unterhalb des angegebenen aktuellen Arbeitsverzeichnisses mit einem Namen, der das Wort route enthält und mit dem Suffix .js endet.

Dateistruktur

Mit Hilfe von Globbing haben wir eine lose Kopplung zwischen dem Objekt server und seinen Routen. Fügen Sie einfach neue Routendateien hinzu und diese werden beim nächsten Neustart Ihres Servers berücksichtigt.

Ich strukturiere die Routendateien gerne nach ihrem Pfad und benenne sie mit ihrer HTTP-Methode wie folgt:

server.js
routes/
    users/
        get-route.js
        patch-route.js
        put-route.js
    articles/
        get-route.js
        patch-route.js
        put-route.js

Beispiel Routendatei routes/users/get-route.js

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

Abschließende Gedanken

Das Verschieben und Durchlaufen von Dateien ist kein besonders schneller Vorgang. Daher kann es sich je nach Ihren Umständen lohnen, eine Caching-Ebene in Produktions-Builds zu untersuchen.

0
Fredric

Ich weiß, dass dies bereits genehmigt ist. Ich schreibe meine Lösung für den Fall auf, dass jemand eine schnelle Lösung wünscht und neu bei Hapi ist.

Ich habe auch ein paar NPM hinzugefügt, damit Newbees sehen können, wie man den server.register Mit mehreren Plugins in dem Fall verwendet (good + hapi-auto-route)

Installierte einige npm-Pakete:

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);
    });
});

In Ihrem 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!');
        } 
    },
];

Führen Sie nun Folgendes aus: node server.js

Prost

0
Mr H