2012-04-02 3 views
10

Ich benutze ExpressJs mit Node.js und habe alle meine Routen in einen 'routes' Ordner gelegt.ExpressJS und Übergabe von Variablen zwischen separaten Routendateien

Auf dem Server kann ich eine DB-Verbindung, dann meine Routen definieren, wie folgt aus:

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

var db; 
dbconnect = new mongo.Db(config.mongo_database, new mongo.Server(config.mongo_host, config.mongo_port, {}), {}); 
dbconnect.open(function (err, db) { 

    db.authenticate(config.mongo_user, config.mongo_pass, function (err, success) { 
    if (success) { 

     //routes/index.js 
     app.get('/', routes.index); 

     //routes/users.js 
     app.get('/users', routes.users); 

    } 
    }); 
}); 

ich den ‚db‘ Objekt innerhalb jeder dieser Routen JavaScript-Dateien zugreifen möchten. Wie würde ich das von dieser 'app.js' Datei an die index.js oder users.js weitergeben?

Vielen Dank!

Antwort

4

Ein Vorschlag ist, Ihre Routen über eine Funktion zu belichten, die einen db Parameter akzeptiert:

routes.js:

module.exports = function(db) { 
    return { 
     index: function(req, res, next) { 
      // Funky db get stuff 
     } 
    } 
} 

Wrapping Werte in einem Verschluss wie diese und mit mehr Funktionen ein Objekt zurückkehr ein nützliches Muster, das manchmal "Modulmuster aufdecken" genannt wird. Es zeigt die Abhängigkeiten klar und ermöglicht ein einfaches Testen (unter Verwendung beispielsweise eines Schein-DB-Objekts), während immer noch ein flexibler funktionaler Ansatz verwendet wird.

+4

Der Nachteil ist jetzt jedes Mal, wenn Sie ein "Modul" über Controller hinweg wiederverwenden möchten, müssen Sie es der Signatur hinzufügen, und Sie können mit Situationen enden, in denen einige Controller 2 benötigen, einige 3 und einer 5, und jetzt hast du eine Signatur, die dem größten gemeinsamen Nenner gerecht werden muss. Ein besserer Ansatz, denke ich, würde sein db-Verhalten in einem lose gekoppelten eigenen Modul kapseln. –

+2

@BradHarris: Das ist definitiv ein Nachteil. Eine Möglichkeit, dieselbe Signatur beizubehalten, wenn Sie das für wichtig halten, ist, stattdessen ein Objekt mit Parametern zu akzeptieren: '{db: db, foo: foo, bar: bar}'. Ihre Lösung ist definitiv kein schlechter Weg, um es zu lösen, obwohl es mit eigenen Nachteilen verbunden ist - es ist schwieriger, Unit-Test, zum einen. –

13

Wenn Sie Ihre Datenbankabstraktion in eine eigene Datei/ein eigenes Modul schreiben, können Sie sie in Ihrer Codebasis nach Bedarf wiederverwenden, indem Sie sie nur dort (wo nötig) benötigen. Es wird nicht neu erstellt, wenn Sie es richtig schreiben, und kann nur einmal beim Start der Anwendung initialisiert werden, wie in Ihrem Beispiel.

Dies ist ein triviales Beispiel, aber hoffentlich wird es den Punkt herüber. In Controller oder alle Dateien, wo Sie das Datenbankobjekt benötigen, nur du ...

var db = require('database'); 

db.init(params, function(err, db) { 
    ... 
}); 


db.query(params, function(err, db) { 
    ... 
}); 

Die Vorteile sind Sie haben jetzt eine lose gekoppelte Datenbankobjekt, das überall in der Anwendung verwendet werden kann, wie jeder andere Knotenmodul durch die require-Anweisung.

+2

Ich mag das. Ein weiteres nützliches Muster ist ein Objekt, das Ihre Anwendung (oder Anwendungsressourcen) als Objekt darstellt. Z.B. require ('./ myapp.js'). db oder require ('./ myapp.js'). config – Prestaul