Next.js+MongoDB开发pages/api接口报collection未定义错误如何解决
问题报错
运行Next.js pages/api路径下的接口时触发报错:Cannot read properties of undefined (reading 'collection')
根因
- 数据库连接为异步操作,原代码在文件顶层调用
connectDB()后未等待连接建立完成,请求进入处理函数时getDB()返回的数据库实例还是undefined,调用collection方法直接报错。 - 原连接模块未做实例缓存,重复调用会创建多余数据库连接。
- 数据库查询代码混用回调与
async/await写法,会导致返回值异常。 - 缺少连接、查询环节的错误兜底,异常发生时接口会直接崩溃。
修复方案
1. 重写数据库连接模块
替换utils/connectdb.js的原有代码,改为带连接缓存的Promise风格实现,避免时序问题和重复连接:
require("dotenv").config(); const { MongoClient } = require("mongodb"); let cachedClient = null; let cachedDb = null; async function connectDB() { // 已存在有效连接时直接返回缓存实例 if (cachedClient && cachedDb) { return { db: cachedDb }; } const connectionUri = process.env.DB; if (!connectionUri) { throw new Error("未配置数据库连接字符串环境变量DB"); } const client = await MongoClient.connect(connectionUri); // 如果连接串未指定库名,需在db()中传入实际业务库名,例如client.db("ecommerce") const db = client.db(); cachedClient = client; cachedDb = db; return { db }; } module.exports = { connectDB };
2. 修改API接口逻辑
替换原有接口代码,在请求处理函数内部等待数据库连接完成后再执行查询,统一使用async/await写法,移除多余的回调逻辑:
import { connectDB } from '../../../utils/connectdb' export default async (req, res) => { try { // 等待数据库连接完成后再获取实例 const { db } = await connectDB(); // 直接await查询结果,不要混用回调写法 const productList = await db.collection('products').find().toArray(); res.status(200).json({ products: productList }); } catch (err) { console.error("接口处理异常:", err); res.status(500).json({ error: "服务端处理失败" }); } }
注意事项
- 检查MongoDB连接串:如果你的
DB环境变量值末尾没有指定数据库名,必须在client.db()方法中传入你实际使用的数据库名称,否则会默认连接到test库,后续查询会出现找不到集合的问题。 - 不要在API路由文件的顶层执行数据库连接操作,Next.js编译阶段会执行顶层代码,容易引发环境变量未加载、连接时序错乱的问题。
- 带缓存的连接逻辑可以避免Serverless部署场景下MongoDB连接数被打满的问题。
内容的提问来源于stack exchange,提问作者Noureddine Bachikh
相关产品推荐
相关产品推荐

