Her er den løsning, jeg har fundet på.
Jeg brugte mongojs hvilket i høj grad forenkler mongodb-grænsefladen - på bekostning af fleksibilitet i konfigurationen - men det skjuler de indlejrede tilbagekald, som mongodb-driveren kræver. Det gør også syntaksen meget mere som mongo-klienten.
Jeg pakker derefter HTTP Response-objektet i en lukning og sender denne lukning til mongodb-forespørgselsmetoden i et tilbagekald.
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);
};
Det er stadig i det væsentlige bare at videregive svarobjektet til databaseudbyderen, men ved at pakke det ind i en lukning, der ved, hvordan man håndterer svaret, holder det den logik ude af mit databasemodul.
En lille forbedring er at bruge en funktion til at oprette en svarhåndteringslukning uden for min anmodningshandler:
function makeSendResponse(response){
return function sendResponse(err, data) {
if (err) {
console.warn(err);
response.send(500, {error: err});
return;
}
response.send(data);
};
}
Så nu ser min anmodningsbehandler bare sådan ud:
exports.index = function(request, response) {
response.send(makeSendResponse(response));
}
Og min MongoProvider ser sådan ud:
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;
Jeg kan også udvide MongoProvider til specifikke samlinger for at forenkle API'et og udføre yderligere validering:
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;