Här är lösningen jag har kommit fram till.
Jag använde mongojs vilket avsevärt förenklar mongodb-gränssnittet --till bekostnad av flexibilitet i konfigurationen-- men det döljer de kapslade återuppringningar som mongodb-drivrutinen kräver. Det gör också syntaxen mycket mer lik mongoklienten.
Jag lindar sedan HTTP-svarsobjektet i en stängning och skickar denna stängning till mongodb-frågemetoden i en återuppringning.
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 är fortfarande i huvudsak bara att skicka svarsobjektet till databasleverantören, men genom att linda in det i en stängning som vet hur man hanterar svaret, håller den logiken borta från min databasmodul.
En liten förbättring är att använda en funktion för att skapa en stängning av svarshanterare utanför min begäranhanterare:
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 begäranhanterare bara ut så här:
exports.index = function(request, response) {
response.send(makeSendResponse(response));
}
Och min MongoProvider ser ut så här:
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;
Jag kan också utöka MongoProvider för specifika samlingar för att förenkla API:et och göra ytterligare 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;