skip to Main Content

This is not so much of a question but more of a consult request. I couldn’t find resources to check my method’s validity so I would like to hear MongoDB experts’ opinion.

I was playing around with MongoDB and came up with this middleware method to pass client to my routes. I have this Express middleware:

const addClientToRequest = async (req, _, next) => {
  const client = new MongoClient(uri);
  await client.connect();
  req.client = client;
  next();
};

app.use(addClientToRequest);

After that, I use req.client in my routes to access my database.

app.get("/:id", async (req, res) => {
  const client = req.client;
  const id = req.params.id;
  try {
    const data = await client.db("mydb").collection("mycollection").findOne({ id });
    if (data) return res.status(200).json(data);
  } catch (error) {
    return res
      .status(500)
      .json({ message: "Error fetching requested data", error });
  }
  return res.status(404).json({ message: "Requested data cannot be found" });
});

What would be a problem in this approach? Is it okay to use MongoDB client like this?

2

Answers


  1. I think that what you could do is to put the client outside of the middleware, so you doesn’t re define it and re connect to it each time a request is done.
    To do so, simply define it and connect before the middleware, and in the middleware, set the client as req.mongoClient or how you want to name it.

    const client = new MongoClient(uri);
    await client.connect(); // if this is outside of an async function, either use an async function like (async () => {..script..})(), either define a variable isClientReady and set it on true after the promise resolved.
    
    const addClientToRequest = (req, _, next) => {
      req.client = client;
      next();
    };
    
    app.use(addClientToRequest);
    
    Login or Signup to reply.
  2. In my experience, we have always defined a separate utility to load a connection pool at the app startup and then reused those connections.

    In the above approach, you seem to be creating a new connection for every HTTP request that is made and then not terminating (or) closing the connection. This may be expensive for a large app.

    db.util.js

    const { MongoClient } = require("mongodb");
    
    const uri = `mongodb://${process.env.DB_USER}:${process.env.DB_PASSWORD}@localhost:27017/${process.env.DATABASE}?maxPoolSize=2-&w=majority`;
    
    const client = new MongoClient(uri);
    
    const init = async () => {
      try {
        await client.connect();
        console.log("Connected");
      } catch (error) {
        console.log(error);
      }
    };
    
    const getClient = () => {
      return client;
    };
    
    module.exports.init = init;
    module.exports.getClient = getClient;
    

    app.js

    //Import modules
    require("dotenv").config({ path: __dirname + "/.env" });
    const express = require("express");
    const dogRoutes = require("./routes/dog.routes");
    const db = require("./utils/db.util");
    
    // Define PORT for HTTP Server
    const PORT = 9900;
    
    // Initialize Express
    const app = express();
    
    app.use(express.json());
    app.use(dogRoutes);
    
    (async () => {
      await db.init();
    
      app.listen(PORT, (err) => {
        console.log(`Server is up at localhost ${PORT}`);
      });
    })();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search