Correct place to query MongoDB in Express API server application with testing? The Next CEO of Stack OverflowHow to query MongoDB with “like”?Error 'Object has no method xxx ' while using Mongooseexport var to routes files expressjsPush items into mongo array via mongooseI seem to get a “new module instance” when calling requiremongodb connection mechanism in express serverCreating a instance using a model shows 'not a function' (node using mongoose)collection level access control with mongooseExtract data from form and add to database using MongooseTypeError: schematype.castForQueryWrapper is not a function

Upgrading From a 9 Speed Sora Derailleur?

Airship steam engine room - problems and conflict

Why doesn't Shulchan Aruch include the laws of destroying fruit trees?

Shortening a title without changing its meaning

How should I connect my cat5 cable to connectors having an orange-green line?

Calculate the Mean mean of two numbers

Creating a script with console commands

What does this strange code stamp on my passport mean?

How does a dynamic QR code work?

Find the majority element, which appears more than half the time

Cannot restore registry to default in Windows 10?

Car headlights in a world without electricity

Could you use a laser beam as a modulated carrier wave for radio signal?

How to compactly explain secondary and tertiary characters without resorting to stereotypes?

Man transported from Alternate World into ours by a Neutrino Detector

How to pronounce fünf in 45

Strange use of "whether ... than ..." in official text

Does Germany produce more waste than the US?

Do I need to write [sic] when including a quotation with a number less than 10 that isn't written out?

How do I secure a TV wall mount?

How can the PCs determine if an item is a phylactery?

Is the offspring between a demon and a celestial possible? If so what is it called and is it in a book somewhere?

What steps are necessary to read a Modern SSD in Medieval Europe?

Finitely generated matrix groups whose eigenvalues are all algebraic



Correct place to query MongoDB in Express API server application with testing?



The Next CEO of Stack OverflowHow to query MongoDB with “like”?Error 'Object has no method xxx ' while using Mongooseexport var to routes files expressjsPush items into mongo array via mongooseI seem to get a “new module instance” when calling requiremongodb connection mechanism in express serverCreating a instance using a model shows 'not a function' (node using mongoose)collection level access control with mongooseExtract data from form and add to database using MongooseTypeError: schematype.castForQueryWrapper is not a function










1















I am creating a Node/Express API server to use as a backend for a React single page application. Currently, I am using the MongoDB Node.js driver (not mongoose) to connect to my MongoDB instance.



My question is where is the correct place to store MongoDB queries (insertOne, FindOne, etc...)? I am hoping that someone with experience in a production team can give some insight.



So far I have been given some advice from people with similar experience, but there seems to be quite a lot of contradiction. Here are the two main practices I've seen:



1. Connect to MongoDB and query inside controller functions.



I have been told that it is okay to connect and query the database from inside the controller functions. Here is an example of how that would look:



App structure:



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── routes
│   └── users.js


Connect to MonogoDB in several functions inside /controllers, reusing the same connection throughout the application as recommended. Here is an example /controllers/users.js:



import initMongo from '../db/mongodb';

export const registerUser = (req, res) =>
initMongo().then((db) =>
// Register User Code Here
);
;


export const loginUser = (req, res) =>
initMongo().then((db) =>
// Login User Code Here
);
;



Here is an example `/db/mongodb.js':



import MongoClient from 'mongodb';

let cachedDb = null;

/**
* @description Initialzies the DB instance.
*
* @returns Promise A resolved promise with the DB instance.
*/
export default () =>
if (cachedDb && cachedDb.serverConfig.isConnected())
return Promise.resolve(cachedDb);


return MongoClient.connect(process.env.MONGO_URL,
useNewUrlParser: true,
).then(client =>
cachedDb = client.db('databaseName');
return Promise.resolve(cachedDb);
);
;


The controller functions are then called by specific routes in /routes/users.js, like so:



router.post('/register', registerUser);
router.post('/login', loginUser);


2. Create a Models folder and store all DB queries there:



I have also been told to break the DB queries out into a models folder and then reference the queries from there in your controllers like so:



App Structure



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── models
│   └── users.js
├── routes
│   └── users.js


Sample /controllers/users.js file:



import UserModel from '../models/users';

export const registerUser = (req, res) =>
const user = new UserModel();
user.createUser(req.body.user);
;


Sample /models/users.js file:



export default function User() 
this.createUser = (newUser) =>
// MongoDB insertOne Query




Is there any benefit to using one of these methods of the other? Is there a recommended way in a multi-person production team? Am I an idiot and should just be using Mongoose?



I would also love to hear opinions on which method would be easier for unit testing with a platform such as Jest.










share|improve this question
























  • I think you have a race condition with "if (...cachedDb.serverConfig.isConnected())", right? I think normal pattern is to cache a promise that returns a db, rather than caching the db itself. (I know that's not what you're asking about, but it's something that jumped out at me)

    – willis
    Mar 7 at 20:18











  • Great question. The reason I have that condition is that in a certain scenario, Mongo could return a DB that isn't actually connected which would blow everything up. I am not sure about the exact scenario though (should have commented it facepalm). Since it would reuse the same connection (not start another), that should avoid the race condition from my understanding, no?

    – Nick B.
    Mar 7 at 20:30







  • 1





    I think the more common pattern is to let the MongoClient worry about connects & reconnects & handle emitted errors. With the code as written, if you start up and call that exported db function 100 times before the first connection completes, you'll connect to mongo 100 times (and eventually end up using the last connection as your cached db).

    – willis
    Mar 7 at 21:01












  • @willis with AWS Lambda, it saves the state of the application. Therefore if it was to power down for say 60 mins, the MongoDB instance would time out. If I didn't have that check, the program would return the saved DB that is not connected, which would ultimately not work. I do see what you are saying though, I would max the database connections if I were to call the function in a fast successive nature. Any ideas on a solution for that? Here is some more info: mongodb.com/blog/post/…

    – Nick B.
    Mar 7 at 21:39











  • @willis since the DB connection function is a promised base function, the second call would not technically run until the first returns a resolved promise with the database, which would stop that problem, no?

    – Nick B.
    Mar 7 at 21:57















1















I am creating a Node/Express API server to use as a backend for a React single page application. Currently, I am using the MongoDB Node.js driver (not mongoose) to connect to my MongoDB instance.



My question is where is the correct place to store MongoDB queries (insertOne, FindOne, etc...)? I am hoping that someone with experience in a production team can give some insight.



So far I have been given some advice from people with similar experience, but there seems to be quite a lot of contradiction. Here are the two main practices I've seen:



1. Connect to MongoDB and query inside controller functions.



I have been told that it is okay to connect and query the database from inside the controller functions. Here is an example of how that would look:



App structure:



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── routes
│   └── users.js


Connect to MonogoDB in several functions inside /controllers, reusing the same connection throughout the application as recommended. Here is an example /controllers/users.js:



import initMongo from '../db/mongodb';

export const registerUser = (req, res) =>
initMongo().then((db) =>
// Register User Code Here
);
;


export const loginUser = (req, res) =>
initMongo().then((db) =>
// Login User Code Here
);
;



Here is an example `/db/mongodb.js':



import MongoClient from 'mongodb';

let cachedDb = null;

/**
* @description Initialzies the DB instance.
*
* @returns Promise A resolved promise with the DB instance.
*/
export default () =>
if (cachedDb && cachedDb.serverConfig.isConnected())
return Promise.resolve(cachedDb);


return MongoClient.connect(process.env.MONGO_URL,
useNewUrlParser: true,
).then(client =>
cachedDb = client.db('databaseName');
return Promise.resolve(cachedDb);
);
;


The controller functions are then called by specific routes in /routes/users.js, like so:



router.post('/register', registerUser);
router.post('/login', loginUser);


2. Create a Models folder and store all DB queries there:



I have also been told to break the DB queries out into a models folder and then reference the queries from there in your controllers like so:



App Structure



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── models
│   └── users.js
├── routes
│   └── users.js


Sample /controllers/users.js file:



import UserModel from '../models/users';

export const registerUser = (req, res) =>
const user = new UserModel();
user.createUser(req.body.user);
;


Sample /models/users.js file:



export default function User() 
this.createUser = (newUser) =>
// MongoDB insertOne Query




Is there any benefit to using one of these methods of the other? Is there a recommended way in a multi-person production team? Am I an idiot and should just be using Mongoose?



I would also love to hear opinions on which method would be easier for unit testing with a platform such as Jest.










share|improve this question
























  • I think you have a race condition with "if (...cachedDb.serverConfig.isConnected())", right? I think normal pattern is to cache a promise that returns a db, rather than caching the db itself. (I know that's not what you're asking about, but it's something that jumped out at me)

    – willis
    Mar 7 at 20:18











  • Great question. The reason I have that condition is that in a certain scenario, Mongo could return a DB that isn't actually connected which would blow everything up. I am not sure about the exact scenario though (should have commented it facepalm). Since it would reuse the same connection (not start another), that should avoid the race condition from my understanding, no?

    – Nick B.
    Mar 7 at 20:30







  • 1





    I think the more common pattern is to let the MongoClient worry about connects & reconnects & handle emitted errors. With the code as written, if you start up and call that exported db function 100 times before the first connection completes, you'll connect to mongo 100 times (and eventually end up using the last connection as your cached db).

    – willis
    Mar 7 at 21:01












  • @willis with AWS Lambda, it saves the state of the application. Therefore if it was to power down for say 60 mins, the MongoDB instance would time out. If I didn't have that check, the program would return the saved DB that is not connected, which would ultimately not work. I do see what you are saying though, I would max the database connections if I were to call the function in a fast successive nature. Any ideas on a solution for that? Here is some more info: mongodb.com/blog/post/…

    – Nick B.
    Mar 7 at 21:39











  • @willis since the DB connection function is a promised base function, the second call would not technically run until the first returns a resolved promise with the database, which would stop that problem, no?

    – Nick B.
    Mar 7 at 21:57













1












1








1


1






I am creating a Node/Express API server to use as a backend for a React single page application. Currently, I am using the MongoDB Node.js driver (not mongoose) to connect to my MongoDB instance.



My question is where is the correct place to store MongoDB queries (insertOne, FindOne, etc...)? I am hoping that someone with experience in a production team can give some insight.



So far I have been given some advice from people with similar experience, but there seems to be quite a lot of contradiction. Here are the two main practices I've seen:



1. Connect to MongoDB and query inside controller functions.



I have been told that it is okay to connect and query the database from inside the controller functions. Here is an example of how that would look:



App structure:



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── routes
│   └── users.js


Connect to MonogoDB in several functions inside /controllers, reusing the same connection throughout the application as recommended. Here is an example /controllers/users.js:



import initMongo from '../db/mongodb';

export const registerUser = (req, res) =>
initMongo().then((db) =>
// Register User Code Here
);
;


export const loginUser = (req, res) =>
initMongo().then((db) =>
// Login User Code Here
);
;



Here is an example `/db/mongodb.js':



import MongoClient from 'mongodb';

let cachedDb = null;

/**
* @description Initialzies the DB instance.
*
* @returns Promise A resolved promise with the DB instance.
*/
export default () =>
if (cachedDb && cachedDb.serverConfig.isConnected())
return Promise.resolve(cachedDb);


return MongoClient.connect(process.env.MONGO_URL,
useNewUrlParser: true,
).then(client =>
cachedDb = client.db('databaseName');
return Promise.resolve(cachedDb);
);
;


The controller functions are then called by specific routes in /routes/users.js, like so:



router.post('/register', registerUser);
router.post('/login', loginUser);


2. Create a Models folder and store all DB queries there:



I have also been told to break the DB queries out into a models folder and then reference the queries from there in your controllers like so:



App Structure



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── models
│   └── users.js
├── routes
│   └── users.js


Sample /controllers/users.js file:



import UserModel from '../models/users';

export const registerUser = (req, res) =>
const user = new UserModel();
user.createUser(req.body.user);
;


Sample /models/users.js file:



export default function User() 
this.createUser = (newUser) =>
// MongoDB insertOne Query




Is there any benefit to using one of these methods of the other? Is there a recommended way in a multi-person production team? Am I an idiot and should just be using Mongoose?



I would also love to hear opinions on which method would be easier for unit testing with a platform such as Jest.










share|improve this question
















I am creating a Node/Express API server to use as a backend for a React single page application. Currently, I am using the MongoDB Node.js driver (not mongoose) to connect to my MongoDB instance.



My question is where is the correct place to store MongoDB queries (insertOne, FindOne, etc...)? I am hoping that someone with experience in a production team can give some insight.



So far I have been given some advice from people with similar experience, but there seems to be quite a lot of contradiction. Here are the two main practices I've seen:



1. Connect to MongoDB and query inside controller functions.



I have been told that it is okay to connect and query the database from inside the controller functions. Here is an example of how that would look:



App structure:



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── routes
│   └── users.js


Connect to MonogoDB in several functions inside /controllers, reusing the same connection throughout the application as recommended. Here is an example /controllers/users.js:



import initMongo from '../db/mongodb';

export const registerUser = (req, res) =>
initMongo().then((db) =>
// Register User Code Here
);
;


export const loginUser = (req, res) =>
initMongo().then((db) =>
// Login User Code Here
);
;



Here is an example `/db/mongodb.js':



import MongoClient from 'mongodb';

let cachedDb = null;

/**
* @description Initialzies the DB instance.
*
* @returns Promise A resolved promise with the DB instance.
*/
export default () =>
if (cachedDb && cachedDb.serverConfig.isConnected())
return Promise.resolve(cachedDb);


return MongoClient.connect(process.env.MONGO_URL,
useNewUrlParser: true,
).then(client =>
cachedDb = client.db('databaseName');
return Promise.resolve(cachedDb);
);
;


The controller functions are then called by specific routes in /routes/users.js, like so:



router.post('/register', registerUser);
router.post('/login', loginUser);


2. Create a Models folder and store all DB queries there:



I have also been told to break the DB queries out into a models folder and then reference the queries from there in your controllers like so:



App Structure



├── app.js
├── controllers
│   └── users.js
├── db
│   └── mongodb.js
├── models
│   └── users.js
├── routes
│   └── users.js


Sample /controllers/users.js file:



import UserModel from '../models/users';

export const registerUser = (req, res) =>
const user = new UserModel();
user.createUser(req.body.user);
;


Sample /models/users.js file:



export default function User() 
this.createUser = (newUser) =>
// MongoDB insertOne Query




Is there any benefit to using one of these methods of the other? Is there a recommended way in a multi-person production team? Am I an idiot and should just be using Mongoose?



I would also love to hear opinions on which method would be easier for unit testing with a platform such as Jest.







node.js mongodb express






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 7 at 19:44







Nick B.

















asked Mar 7 at 19:36









Nick B.Nick B.

150110




150110












  • I think you have a race condition with "if (...cachedDb.serverConfig.isConnected())", right? I think normal pattern is to cache a promise that returns a db, rather than caching the db itself. (I know that's not what you're asking about, but it's something that jumped out at me)

    – willis
    Mar 7 at 20:18











  • Great question. The reason I have that condition is that in a certain scenario, Mongo could return a DB that isn't actually connected which would blow everything up. I am not sure about the exact scenario though (should have commented it facepalm). Since it would reuse the same connection (not start another), that should avoid the race condition from my understanding, no?

    – Nick B.
    Mar 7 at 20:30







  • 1





    I think the more common pattern is to let the MongoClient worry about connects & reconnects & handle emitted errors. With the code as written, if you start up and call that exported db function 100 times before the first connection completes, you'll connect to mongo 100 times (and eventually end up using the last connection as your cached db).

    – willis
    Mar 7 at 21:01












  • @willis with AWS Lambda, it saves the state of the application. Therefore if it was to power down for say 60 mins, the MongoDB instance would time out. If I didn't have that check, the program would return the saved DB that is not connected, which would ultimately not work. I do see what you are saying though, I would max the database connections if I were to call the function in a fast successive nature. Any ideas on a solution for that? Here is some more info: mongodb.com/blog/post/…

    – Nick B.
    Mar 7 at 21:39











  • @willis since the DB connection function is a promised base function, the second call would not technically run until the first returns a resolved promise with the database, which would stop that problem, no?

    – Nick B.
    Mar 7 at 21:57

















  • I think you have a race condition with "if (...cachedDb.serverConfig.isConnected())", right? I think normal pattern is to cache a promise that returns a db, rather than caching the db itself. (I know that's not what you're asking about, but it's something that jumped out at me)

    – willis
    Mar 7 at 20:18











  • Great question. The reason I have that condition is that in a certain scenario, Mongo could return a DB that isn't actually connected which would blow everything up. I am not sure about the exact scenario though (should have commented it facepalm). Since it would reuse the same connection (not start another), that should avoid the race condition from my understanding, no?

    – Nick B.
    Mar 7 at 20:30







  • 1





    I think the more common pattern is to let the MongoClient worry about connects & reconnects & handle emitted errors. With the code as written, if you start up and call that exported db function 100 times before the first connection completes, you'll connect to mongo 100 times (and eventually end up using the last connection as your cached db).

    – willis
    Mar 7 at 21:01












  • @willis with AWS Lambda, it saves the state of the application. Therefore if it was to power down for say 60 mins, the MongoDB instance would time out. If I didn't have that check, the program would return the saved DB that is not connected, which would ultimately not work. I do see what you are saying though, I would max the database connections if I were to call the function in a fast successive nature. Any ideas on a solution for that? Here is some more info: mongodb.com/blog/post/…

    – Nick B.
    Mar 7 at 21:39











  • @willis since the DB connection function is a promised base function, the second call would not technically run until the first returns a resolved promise with the database, which would stop that problem, no?

    – Nick B.
    Mar 7 at 21:57
















I think you have a race condition with "if (...cachedDb.serverConfig.isConnected())", right? I think normal pattern is to cache a promise that returns a db, rather than caching the db itself. (I know that's not what you're asking about, but it's something that jumped out at me)

– willis
Mar 7 at 20:18





I think you have a race condition with "if (...cachedDb.serverConfig.isConnected())", right? I think normal pattern is to cache a promise that returns a db, rather than caching the db itself. (I know that's not what you're asking about, but it's something that jumped out at me)

– willis
Mar 7 at 20:18













Great question. The reason I have that condition is that in a certain scenario, Mongo could return a DB that isn't actually connected which would blow everything up. I am not sure about the exact scenario though (should have commented it facepalm). Since it would reuse the same connection (not start another), that should avoid the race condition from my understanding, no?

– Nick B.
Mar 7 at 20:30






Great question. The reason I have that condition is that in a certain scenario, Mongo could return a DB that isn't actually connected which would blow everything up. I am not sure about the exact scenario though (should have commented it facepalm). Since it would reuse the same connection (not start another), that should avoid the race condition from my understanding, no?

– Nick B.
Mar 7 at 20:30





1




1





I think the more common pattern is to let the MongoClient worry about connects & reconnects & handle emitted errors. With the code as written, if you start up and call that exported db function 100 times before the first connection completes, you'll connect to mongo 100 times (and eventually end up using the last connection as your cached db).

– willis
Mar 7 at 21:01






I think the more common pattern is to let the MongoClient worry about connects & reconnects & handle emitted errors. With the code as written, if you start up and call that exported db function 100 times before the first connection completes, you'll connect to mongo 100 times (and eventually end up using the last connection as your cached db).

– willis
Mar 7 at 21:01














@willis with AWS Lambda, it saves the state of the application. Therefore if it was to power down for say 60 mins, the MongoDB instance would time out. If I didn't have that check, the program would return the saved DB that is not connected, which would ultimately not work. I do see what you are saying though, I would max the database connections if I were to call the function in a fast successive nature. Any ideas on a solution for that? Here is some more info: mongodb.com/blog/post/…

– Nick B.
Mar 7 at 21:39





@willis with AWS Lambda, it saves the state of the application. Therefore if it was to power down for say 60 mins, the MongoDB instance would time out. If I didn't have that check, the program would return the saved DB that is not connected, which would ultimately not work. I do see what you are saying though, I would max the database connections if I were to call the function in a fast successive nature. Any ideas on a solution for that? Here is some more info: mongodb.com/blog/post/…

– Nick B.
Mar 7 at 21:39













@willis since the DB connection function is a promised base function, the second call would not technically run until the first returns a resolved promise with the database, which would stop that problem, no?

– Nick B.
Mar 7 at 21:57





@willis since the DB connection function is a promised base function, the second call would not technically run until the first returns a resolved promise with the database, which would stop that problem, no?

– Nick B.
Mar 7 at 21:57












0






active

oldest

votes












Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55051558%2fcorrect-place-to-query-mongodb-in-express-api-server-application-with-testing%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55051558%2fcorrect-place-to-query-mongodb-in-express-api-server-application-with-testing%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

1928 у кіно

Захаров Федір Захарович

Ель Греко