MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

So verwenden Sie Ereignisse, um die Mongodb-Logik aus den Anfrage-Handlern von node.js herauszuhalten

Hier ist die Lösung, die ich mir ausgedacht habe.

Ich habe mongojs verwendet Dies vereinfacht die mongodb-Schnittstelle erheblich - auf Kosten der Flexibilität bei der Konfiguration -, verbirgt jedoch die verschachtelten Rückrufe, die der mongodb-Treiber benötigt. Es macht auch die Syntax dem Mongo-Client viel ähnlicher.

Dann verpacke ich das HTTP-Response-Objekt in eine Closure und übergebe diese Closure in einem Callback an die mongodb-Abfragemethode.

var MongoProvider = require('./MongoProvider');
MongoProvider.setCollection('things');

exports.index = function(request, response){
    function sendResponse(err, data) {
        if (err) { 
            response.send(500, err);
        }    
        response.send(data);
    };

    MongoProvider.fetchAll(things, sendResponse);
};

Es übergibt im Wesentlichen immer noch nur das Antwortobjekt an den Datenbankanbieter, aber indem es es in eine Closure einschließt, die weiß, wie die Antwort zu handhaben ist, hält es diese Logik aus meinem Datenbankmodul heraus.

Eine leichte Verbesserung besteht darin, eine Funktion zu verwenden, um einen Response-Handler-Closure außerhalb meines Request-Handlers zu erstellen:

function makeSendResponse(response){
    return function sendResponse(err, data) {
        if (err) {
            console.warn(err);
            response.send(500, {error: err});
            return;
        }

        response.send(data);
    };
}

Jetzt sieht mein Request-Handler also einfach so aus:

exports.index = function(request, response) {
    response.send(makeSendResponse(response));
}

Und mein MongoProvider sieht so aus:

var mongojs = require('mongojs');

MongoProvider = function(config) {
this.configure(config);
    this.db = mongojs.connect(this.url, this.collections);
}

MongoProvider.prototype.configure = function(config) {
    this.url = config.host + "/" + config.name;
    this.collections = config.collections;
}

MongoProvider.prototype.connect = function(url, collections) {
    return mongojs.connect(this.url, this.collections);
}

MongoProvider.prototype.fetchAll = function fetchAll(collection, callback) {
    this.db(collection).find(callback);
}

MongoProvider.prototype.fetchById = function fetchById(id, collection, callback) {
    var objectId = collection.db.bson_serializer.ObjectID.createFromHexString(id.toString());

    this.db(collection).findOne({ "_id": objectId }, callback);
}

MongoProvider.prototype.fetchMatches = function fetchMatches(json, collection, callback) {
    this.db(collection).find(Json.parse(json), callback);
}

module.exports = MongoProvider;

Ich kann MongoProvider auch für bestimmte Sammlungen erweitern, um die API zu vereinfachen und zusätzliche Validierungen durchzuführen:

ThingsProvider = function(config) {
    this.collection = 'things';
    this.mongoProvider = new MongoProvider(config);
    things = mongoProvider.db.collection('things');
}

ThingsProvider.prototype.fetchAll = function(callback) {
    things.fetchAll(callback);
}

//etc...

module.exports = ThingsProvider;