Next.js API路由跨端点读写内存变量失效问题咨询
问题
我有多个Next.js API路由,想要读写在另一个文件中定义的内存对象,但遇到了问题。具体场景如下:
在inMemoryDB.ts中定义了testDB对象,在pages/api/in-memory-test/endpoint1.ts的GET接口中修改testDB['key1'].name为'john',修改在该端点内有效,但后续调用pages/api/in-memory-test/endpoint2.ts的POST接口时,读取到的testDB['key1'].name仍为初始值'jane'。
相关代码如下:
inMemoryDB.ts
export const testDB = { ['key1']: { id: 'key1', name: 'jane' } };
pages/api/in-memory-test/endpoint1.ts
import type { NextApiRequest, NextApiResponse } from 'next'; import { testDB } from '../../../src/constants/inMemoryDB'; export default function handler(req: NextApiRequest, res: NextApiResponse) { switch (req.method) { case 'GET': return getEndpoint1(req, res); default: return res.status(400).json({ message: 'Bad request' }); } } const getEndpoint1 = async (req: NextApiRequest, res: NextApiResponse) => { console.log('[testDB - 1]', testDB); testDB['key1'].name = 'john'; return res.status(200).json({ testDB }); };
pages/api/in-memory-test/endpoint2.ts
import type { NextApiRequest, NextApiResponse } from 'next'; import { testDB } from '../../../src/constants/inMemoryDB'; export default function handler(req: NextApiRequest, res: NextApiResponse) { switch (req.method) { case 'POST': return postEndpoint2(req, res); default: return res.status(400).json({ message: 'Bad request' }); } } const postEndpoint2 = async (req: NextApiRequest, res: NextApiResponse) => { return res.status(200).json({ testDB }); };
调用endpoint1的GET接口后返回的testDB中key1.name为'john',但调用endpoint2的POST接口时返回的testDB中key1.name仍为'jane',请问该如何实现跨API端点共享并修改内存变量?
原因与解决方案
问题根源
Next.js的API路由在生产环境是无状态的Serverless函数,每个请求可能被分配到不同的服务器实例,或者同一实例在请求结束后被销毁重置。就算在开发环境,热重载或请求隔离机制也会导致内存对象无法跨请求共享——你修改的只是当前请求实例里的testDB,其他请求读的还是初始值。
可行解决方式
1. 单例模式封装内存对象(单实例环境可用)
把内存对象封装成单例,确保所有API路由引用的是同一个实例。修改inMemoryDB.ts:
class InMemoryDB { private static instance: InMemoryDB; public data = { ['key1']: { id: 'key1', name: 'jane' } }; private constructor() {} public static getInstance(): InMemoryDB { if (!InMemoryDB.instance) { InMemoryDB.instance = new InMemoryDB(); } return InMemoryDB.instance; } } export const testDB = InMemoryDB.getInstance().data;
这样所有API路由导入的testDB都是同一个内存对象的引用,修改后跨端点能读到最新值。
注意:这种方式只在单服务器实例环境下生效,像Vercel生产环境这种多实例部署场景,不同实例的内存还是隔离的,得用外部存储。
2. 外部存储(生产环境推荐)
如果是生产环境或多实例部署,内存变量无法跨实例共享,建议用外部存储:
- 轻量场景:用Redis做内存缓存,读写快且支持跨实例共享
- 持久化场景:用MySQL、PostgreSQL等数据库存储数据
Redis简化示例:
// 先安装依赖:npm i redis import { createClient } from 'redis'; const client = createClient({ url: 'redis://localhost:6379' }); client.connect(); // endpoint1中修改值 await client.set('key1', JSON.stringify({ id: 'key1', name: 'john' })); // endpoint2中读取值 const data = await client.get('key1'); const testDB = { key1: JSON.parse(data) };
额外提醒
- 开发环境下,Next.js的热重载可能重置内存对象,测试时可以关闭热重载或重启服务验证
- 内存存储的数据在服务器重启后会丢失,不适合存需要持久化的重要数据
内容的提问来源于stack exchange,提问作者sara lance

