NextJS 13中如何在API路由间共享数据库连接?
在NextJS 13中共享MongoDB连接的正确姿势
要在NextJS 13的API路由(或服务器组件)间复用MongoClient实例,核心是利用Node.js模块的单例特性,同时处理开发模式下的热重载问题。以下是具体实现步骤:
1. 创建全局连接管理文件
在项目根目录下新建lib/mongodb.ts(或.js),用模块级变量+全局对象存储连接实例,避免重复创建:
import { MongoClient } from 'mongodb'; const uri = process.env.MONGODB_URI!; const connectionOptions = { maxPoolSize: 10, // 根据需求调整连接池大小 connectTimeoutMS: 30000, }; // 模块级变量存储客户端和连接Promise let mongoClient: MongoClient; let mongoClientPromise: Promise<MongoClient>; if (!process.env.MONGODB_URI) { throw new Error('请在.env.local中配置MONGODB_URI环境变量'); } if (process.env.NODE_ENV === 'development') { // 开发模式下用globalThis存储,避免热重载重置连接 if (!global._mongoClientPromise) { mongoClient = new MongoClient(uri, connectionOptions); global._mongoClientPromise = mongoClient.connect(); } mongoClientPromise = global._mongoClientPromise; } else { // 生产模式下直接用模块级变量,模块不会被热重载 mongoClient = new MongoClient(uri, connectionOptions); mongoClientPromise = mongoClient.connect(); } export default mongoClientPromise;
2. 在API路由中复用连接
任何需要数据库操作的API路由(比如app/api/posts/route.ts),直接导入这个连接Promise即可:
import clientPromise from '@/lib/mongodb'; import { NextResponse } from 'next/server'; export async function GET() { // 等待连接就绪(只会在第一次调用时建立连接,后续复用) const client = await clientPromise; const db = client.db('your_database_name'); // 执行数据库操作 const posts = await db.collection('posts').find().limit(10).toArray(); return NextResponse.json(posts); }
关键说明
- 为什么之前的测试变量不同步?:开发模式下NextJS的热重载会重新加载模块,普通模块级变量会被重置。用
globalThis存储连接Promise,就能避开这个问题——globalThis在热重载时不会被清空。 - 无需'use client':整个逻辑都运行在服务器端,所有API路由和服务器组件都能直接导入使用,完全不影响客户端性能。
- 连接池自动复用:MongoClient本身会维护连接池,所有请求共享同一池中的连接,无需手动管理。
注意事项
- 确保MongoDB Atlas的IP白名单配置正确(允许Vercel或你的本地IP访问)。
- 根据业务需求调整连接池大小(
maxPoolSize),避免资源浪费或连接不足。 - 生产模式下,模块只会加载一次,连接只会建立一次,所有路由共享同一实例。
内容的提问来源于stack exchange,提问作者Sylith
相关产品推荐
相关产品推荐

