在TypeScript中使用Prisma Middleware添加自定义缓存参数的方法
解决Prisma查询添加cacheTTL/cacheKey的TypeScript编译错误
1. 扩展Prisma的查询参数类型
Prisma默认的查询参数类型(比如UserFindUniqueArgs)不包含cacheTTL和cacheKey字段,需要通过TypeScript模块扩展来添加这些自定义属性。
在项目TypeScript可识别的目录(比如src/types/)下创建prisma-types.d.ts文件,内容如下:
import { Prisma } from '@prisma/client'; // 给所有Prisma查询操作添加可选缓存参数 declare module '@prisma/client' { type CacheArgs = { cacheTTL?: number; cacheKey?: string; }; // 为需要支持缓存的查询类型扩展字段,这里以user的查询为例 interface UserFindUniqueArgs extends CacheArgs {} interface UserFindManyArgs extends CacheArgs {} // 其他模型的查询操作需要支持的话,继续添加对应的Args类型,比如PostFindUniqueArgs等 } // 让Prisma内部运行时也能识别这些参数 declare module '@prisma/client/runtime/library' { interface InternalArgs { cacheTTL?: number; cacheKey?: string; } }
2. 在Middleware中处理自定义缓存参数
你的Prisma Middleware需要读取这些自定义参数,同时要在执行原生查询前移除它们(避免Prisma报错),示例代码:
import { Prisma } from '@prisma/client'; import Redis from 'ioredis'; const redis = new Redis(); const cacheMiddleware: Prisma.Middleware = async (params, next) => { const { args } = params; // 提取自定义缓存参数 const { cacheTTL, cacheKey } = args; // 移除参数,防止Prisma原生查询无法识别 delete args.cacheTTL; delete args.cacheKey; // 优先从Redis读取缓存 if (cacheKey) { const cachedData = await redis.get(cacheKey); if (cachedData) { return JSON.parse(cachedData); } } // 执行原始数据库查询 const result = await next(params); // 将结果存入Redis(如果配置了缓存参数) if (cacheKey && cacheTTL) { await redis.setex(cacheKey, cacheTTL, JSON.stringify(result)); } return result; }; // 给Prisma客户端挂载中间件 const prisma = new PrismaClient().$use(cacheMiddleware);
3. 验证查询代码
现在你的原查询代码不会再触发TypeScript编译错误:
const user = await prisma.user.findUnique({ where: { id: userId }, select: { permissions: { select: { permission: { select: { name: true } } } }, groups: { select: { group: { select: { permissions: { select: { permission: { select: { name: true } } }, }, }, }, }, }, }, cacheTTL: 60 * 10, cacheKey: `user_${userId}_permissions`, });
内容的提问来源于stack exchange,提问作者KatGaea
相关产品推荐
相关产品推荐

