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
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
|
show 2 more comments
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
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
|
show 2 more comments
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
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
node.js mongodb express
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
|
show 2 more comments
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
|
show 2 more comments
0
active
oldest
votes
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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