NestJs 上放置 prisma 中间件的最佳位置在哪里?

zed*_*ian 6 nestjs prisma

我的prisma.service.ts看起来像这样:

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }

  async enableShutdownHooks(app: INestApplication) {
    this.$on('beforeExit', async () => {
      await app.close();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

根据Prisma 文档,我应该将它们放在请求处理程序的上下文之外。这将是我在main.ts上创建的应用程序。在定义应用程序本身之前将中间件放在那里对我来说看起来很奇怪并且不起作用。我更愿意将其放在prisma.service.ts文件本身上

Jou*_*usi 15

不确定这是否是注册它们的“最佳”位置,但我们在服务的构造函数中与日志记录配置一起执行此操作,并且它有效:

import { INestApplication, Injectable, Logger, OnModuleInit } from "@nestjs/common";
import { Prisma, PrismaClient } from "@prisma/client";
import { ConcurrencyErrorMiddleware } from "./concurrency-error.middleware";

@Injectable()
export class PrismaService extends PrismaClient<Prisma.PrismaClientOptions, "query"> implements OnModuleInit {
  private readonly logger = new Logger(PrismaService.name);

  constructor() {
    super({ log: [{ emit: "event", level: "query" }] });

    this.logger.log(`Prisma v${Prisma.prismaVersion.client}`);
    this.$on("query", (e) => this.logger.debug(`${e.query} ${e.params}`));

    this.$use(ConcurrencyErrorMiddleware());
  }

  async onModuleInit(): Promise<void> {
    await this.$connect();
  }

  async enableShutdownHooks(app: INestApplication): Promise<void> {
    this.$on("beforeExit", async () => {
      await app.close();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)
// An example of such a middleware.
import { Prisma } from "@prisma/client";

export function ConcurrencyErrorMiddleware<T extends Prisma.BatchPayload = Prisma.BatchPayload>(): Prisma.Middleware {
  return async (params: Prisma.MiddlewareParams, next: (params: Prisma.MiddlewareParams) => Promise<T>): Promise<T> => {
    const result = await next(params);
    if (
      (params.action === "updateMany" || params.action === "deleteMany") &&
      params.args.where.version &&
      result.count === 0
    ) {
      throw new ConcurrencyError();
    }
    return result;
  };
}
Run Code Online (Sandbox Code Playgroud)