MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment utiliser les événements pour garder la logique mongodb hors des gestionnaires de requêtes node.js

Voici la solution que j'ai trouvé.

J'ai utilisé mongojs ce qui simplifie grandement l'interface mongodb - au détriment de la flexibilité de la configuration - mais il masque les rappels imbriqués requis par le pilote mongodb. Cela rend également la syntaxe beaucoup plus proche du client mongo.

J'enveloppe ensuite l'objet HTTP Response dans une fermeture et je transmets cette fermeture à la méthode de requête mongodb dans un rappel.

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

Il s'agit toujours essentiellement de transmettre l'objet de réponse au fournisseur de base de données, mais en l'enveloppant dans une fermeture qui sait comment gérer la réponse, il garde cette logique hors de mon module de base de données.

Une légère amélioration consiste à utiliser une fonction pour créer une fermeture de gestionnaire de réponse en dehors de mon gestionnaire de requête :

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

        response.send(data);
    };
}

Alors maintenant, mon gestionnaire de requêtes ressemble à ceci :

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

Et mon MongoProvider ressemble à ceci :

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;

Je peux également étendre MongoProvider pour des collections spécifiques afin de simplifier l'API et d'effectuer une validation supplémentaire :

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;