NestJS集成Prisma(Postgres):用Prisma Extension替换废弃的$use中间件
替换废弃的Prisma $use中间件为Prisma Extension
Prisma的$use中间件已被废弃,推荐使用Prisma Extension来实现相同的缓存删除逻辑。以下是替换后的PrismaService实现,保持了原有的调用接口(可直接使用prisma.user.update()):
import { Injectable, OnModuleInit, OnModuleDestroy, Inject } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; import { Cache } from 'cache-manager'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; @Injectable() export class PrismaService implements OnModuleInit, OnModuleDestroy { private readonly client: PrismaClient; constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) { // 初始化基础Prisma客户端 const baseClient = new PrismaClient(); // 通过Extension实现用户更新后的缓存清理逻辑 this.client = baseClient.$extends({ query: { user: { async update({ args, query }) { // 删除目标用户的缓存 const cacheKey = `user:${args.where.id}`; await cacheManager.del(cacheKey); // 执行原始的更新查询 return query(args); }, }, }, }); // 用Proxy让Service实例直接拥有Prisma Client的所有方法 return new Proxy(this, { get(target, prop) { // 优先返回Service自身的属性/方法(如onModuleInit) if (prop in target) { return Reflect.get(target, prop); } // 其余属性/方法委托给扩展后的Prisma Client return Reflect.get(target.client, prop); }, }) as PrismaService & PrismaClient; } async onModuleInit() { await this.client.$connect(); } async onModuleDestroy() { await this.client.$disconnect(); } }
核心修改说明
使用
$extends定义扩展逻辑:- 针对
User模型的update操作单独定义拦截逻辑,在执行更新前清理对应用户的缓存。 - 扩展中的
update方法接收args(查询参数)和query(原始查询执行函数),确保缓存清理后正常执行更新操作。
- 针对
Proxy代理保持接口一致性:
- 通过Proxy对象封装Service实例,让外部调用无需修改原有代码(仍可直接使用
prisma.user.update()),同时保留Service自身的生命周期方法。
- 通过Proxy对象封装Service实例,让外部调用无需修改原有代码(仍可直接使用
简化方案(可选)
如果不介意调整现有代码的调用方式,可以使用更简洁的实现,将扩展后的客户端作为Service的属性:
import { Injectable, OnModuleInit, OnModuleDestroy, Inject } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; import { Cache } from 'cache-manager'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; @Injectable() export class PrismaService implements OnModuleInit, OnModuleDestroy { public readonly client: PrismaClient; constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) { const baseClient = new PrismaClient(); this.client = baseClient.$extends({ query: { user: { async update({ args, query }) { await cacheManager.del(`user:${args.where.id}`); return query(args); }, }, }, }); } async onModuleInit() { await this.client.$connect(); } async onModuleDestroy() { await this.client.$disconnect(); } }
使用时需改为prismaService.client.user.update(...)。
内容的提问来源于stack exchange,提问作者Bernard
相关产品推荐
相关产品推荐

