使用Express和MongoDB,但不使用Mongoose

5
这不是一个问题,而是一个咨询请求。我找不到资源来检查我的方法是否有效,因此我想听一下MongoDB专家的意见。
我正在使用MongoDB并构建了这个中间件方法来将客户端传递给我的路由。我有以下Express中间件:
const addClientToRequest = async (req, _, next) => {
  const client = new MongoClient(uri);
  await client.connect();
  req.client = client;
  next();
};

app.use(addClientToRequest);

之后,我在我的路由中使用req.client来访问我的数据库。

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" });
});

这种方法存在什么问题?使用MongoDB客户端是否可以这样做?

你可以使用以下的方法来组织你的代码: 1) 数据库访问 (连接使用 MongoClient), 2) CRUD(以及其他查询)操作的方法,以及 3) 访问数据库查询的路由代码。在应用程序开始时,你只需要连接一次数据库,然后在应用程序中重复使用该连接即可 (连接与池相关联)。 - prasad_
2个回答

3

根据我的经验,我们一直定义了一个单独的实用程序,在应用程序启动时加载连接池,然后重复使用这些连接。

在上述方法中,您似乎为每个HTTP请求创建一个新连接,然后不终止(或关闭)该连接。对于大型应用程序来说,这可能很昂贵。

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}`);
  });
})();

1
经过一些研究,我也想出了一个与你的解决方案非常相似的解决方案。感谢你的解释。 - zimmerbimmer

0
我认为你可以将客户端放在中间件之外,这样就不需要每次请求时重新定义和重新连接它了。 要做到这一点,只需在中间件之前定义并连接它,在中间件中将客户端设置为req.mongoClient或您想要命名的方式即可。
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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接