You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
  }
}

核心修改说明

  1. 使用$extends定义扩展逻辑:

    • 针对User模型的update操作单独定义拦截逻辑,在执行更新前清理对应用户的缓存。
    • 扩展中的update方法接收args(查询参数)和query(原始查询执行函数),确保缓存清理后正常执行更新操作。
  2. Proxy代理保持接口一致性:

    • 通过Proxy对象封装Service实例,让外部调用无需修改原有代码(仍可直接使用prisma.user.update()),同时保留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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:38:12