It is not clear how to access the object / data access level in the Express / MongoDB application

I have an Express application working with MongoDB. I want to separate the database access from the server level. However, to get the result of a database call, I can only do one of two things:

Pass Res as an argument

//server.js ... var dbApi = require('../data/db-api.js'); ... app.get('/api/user', dbApi.getUsers(function (data) { res.send(data); })); ... //db-api.js ... getUsers: function (callback) { MongoClient.connect(url, function (err, db) { if (err) { throw err; } db.collection(collections.Users) .find({}) .toArray(function (error, documents) { db.close(); callback(documents); }); }); } ... 

Suppose the req / res Express paradigm in db-api.js

 //server.js ... var dbApi = require('../data/db-api.js'); ... app.get('/api/user', dbApi.getUsers); ... //db-api.js ... getUsers: function (req, res) { MongoClient.connect(url, function (err, db) { if (err) { throw err; } db.collection(collections.Users) .find({}) .toArray(function (error, documents) { db.close(); res.send(documents); }); }); } ... 

However, I feel that both of these approaches add implicit dependencies that I would rather avoid. I would prefer to call dbApi independently in server.js so that it returns a result set that I can manipulate before returning, i.e.:

 //server.js ... var dbApi = require('../data/db-api.js'); ... app.get('/api/user', function (req, res) { var result = dbApi.getUsers(); //do stuff with result as necessary res.send(result); }); ... //db-api.js getUsers: function () { MongoClient.connect(url, function (err, db) { if (err) { throw err; } db.collection(collections.Users) .find({}) .toArray(function (error, documents) { db.close(); return documents; }); }); } 

But this last one, it seems, does not want to work, since documents do not return to the server level (the result is undefined). I know this because I am trying to do something synchronously, which is essentially asynchronous.

So, I guess what I'm looking for is tips for best practices regarding application architecture, as it relates to sharing data access level.

+8
javascript architecture mongodb express
source share
2 answers

Well, you can use the promised version of mongo client , return the promise of this value and use async / await. See, for example, this answer .

0
source share

A little late for the party, but, in my opinion, the separation should be that the Express handler processes the HTTP request, and your other method is the database.

Extending the source script and using callbacks:

 //server.js ... var dbApi = require('../data/db-api.js'); ... app.get('/api/user', (req, res) => { try { dbApi.getUsers((documents) => res.send(documents)) } catch (error) { // or something along those lines res.status(500).send({ error: error.message }); } }); ... //db-api.js ... getUsers: function () { MongoClient.connect(url, function (err, db) { if (err) { throw err; } db.collection(collections.Users) .find({}) .toArray(function (error, documents) { db.close(); if (error) { throw error; } return documents; }); }); } 

Sam H. is also right, I promised / asynchronized this to make it more intuitive, current versions of the Mongodb client on the node will return a promise if you do not provide a callback:

 //server.js ... const dbApi = require('../data/db-api.js'); ... app.get('/api/user', async (req, res) => { try { const documents = await dbApi.getUsers(); res.send(documents) } catch (error) { // or something along those lines res.status(500).send({ error: error.message }); } }); ... //db-api.js ... getUsers: async function () { const db = await MongoClient.connect(url); const collection = await db.collection(collections.Users); const query = await collection.find({}); const documents = await query.toArray(); await db.close(); return documents; } 

Or with promises:

 //server.js ... const dbApi = require('../data/db-api.js'); ... app.get('/api/user', (req, res) => { dbApi.getUsers() .then(documents => res.send(documents)) .catch(error => res.status(500).send({ error: error.message }) }); ... //db-api.js ... getUsers: function () { return MongoClient.connect(url) .then(db => Promise.all([ db, db.collection(collections.Users).find({}).toArray() ])) .then(([db, documents]) => Promise.all([documents, db.close()]) .then(([documents]) => documents) } 
0
source share

All Articles