DEV Community

Periklis Gkolias
Periklis Gkolias

Posted on

How to initialize a Singleton mongo connection with expressjs

I am trying to initialize a mongo Singleton connection with expressjs in the app/server.js file, in an async manner. I want to use the native driver and not Mongoose or something similar.

The whole internet is filled with bad patterns (IMHO) that open a new connection with each request.

Has anyone tried and succeeded in the former? Any link or advise will be appreciated.

For example

// app.js
let client = await initMongoConnection()

Top comments (7)

avalander profile image
Avalander • Edited

What I do is initialize the database connection, plus any other asynchronous initialization I need to do, and then bootstrap the entire application and send the connection to any component that needs it.

So basically what your snippet is hinting at:


const startApp = db => {
  const app = express()
  app.use('/', makeApi(db))
  app.listen(PORT, () => console.log(`Server started on port ${PORT}`))

You can check this project I built a while ago for a complete example.

perigk profile image
Periklis Gkolias

Your approach looks very interesting. And cleverly simple as hell. I was trying to do it strictly with await calling anonymous functions on the fly, but this looks very promising :)

Thanks a lot

avalander profile image

Glad it helped :)

this looks very promising

I hope this was an intended pun :D

Thread Thread
perigk profile image
Periklis Gkolias

hahaha, no I just noticed what I did :D

aramix profile image
Aram Bayadyan

if you are using mongoose then you can create a mongoose.js as a middleware where you initialize your connection like so:

const mongoose = require('mongoose');

module.exports = function () {
  const { MONGO_CLUSTER_URL = 'mongodb://', MONGO_DATABASE_NAME } = process.env;

  // Configure mongoose to use Promises, because callbacks are passe.
  mongoose.Promise = global.Promise;
  // Connect to the Mongo DB
  return mongoose.connect(`${MONGO_CLUSTER_URL}/${MONGO_DATABASE_NAME}`, {
    useCreateIndex: true,
    useNewUrlParser: true,
    useUnifiedTopology: true,
Enter fullscreen mode Exit fullscreen mode

and then in your server.js

const mongooseMiddleware = require('./middlewares/mongoose.js');


  .then(() => createServer(app).listen())
  .catch((err) => {
    // an error occurred connecting to mongo!
    // log the error and exit
    console.error('Unable to connect to mongo.');
Enter fullscreen mode Exit fullscreen mode

you can call any mongoose model after this without initializing the connection again

bradtaniguchi profile image

I've used a few patterns:

  1. Create a connection to the DB before the app starts, provide the db connection to who needs it. @avalander provided an example.
  2. Create a map of database connections. This is the same as the first setup, but allows you to have multiple db connections open in a "pool" based upon users. (This was done due to having to connect to multiple databases)
  3. Use Dependency Injection using a lib, your own, or framework (hello nestjs)

I personally find the DI setup is the easiest, but requires the most legwork to get setup. The architecture scales better once you have more dependencies, or dependencies of dependencies or more complexity beyond waiting for 1 thing to "load". (you need to get a config to load before starting mongo, passing extra DB connections to multiple controllers, etc)

Generally opening 1 mongodb connection per request is the worst way to go about things, unless you only have 1 endpoint and or client-side caching or some other layer of caching.

perigk profile image
Periklis Gkolias

Apart from too many articles, I have seen in actual apps too, unfortunately (the one connection per request). I will have a look at nest.js