Skip to content

Prisma 4.16.0 deprecation: Use $extends instead of $use #2822

Open
@apss-pohl

Description

@apss-pohl

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

I have a prisma service along the lines of the offical documentation: https://docs.nestjs.com/recipes/prisma#use-prisma-client-in-your-nestjs-services

Within the "onModuleInit" function i registered a middleware:

  /**
   * Init prisma and attach DB history log
   *
   */
  async onModuleInit() {
    await this.$connect();
    this.$use(async (parameters: Prisma.MiddlewareParams, next) => {
// DO STUFF
    });
  }

With prisma 4.16.0 "$use" became deprecated and the replacement:

Deprecated: Middleware is deprecated in version 4.16.0.
We recommend using the Prisma Client extensions query component type as an alternative to middleware. Prisma Client extensions were first introduced into Preview in version 4.7.0 and made Generally Available in 4.16.0.
Prisma Client extensions allow you to create independent Prisma Client instances and bind each client to a specific filter or user. For example, you could bind clients to specific users to provide user isolation. Prisma Client extensions also provide end-to-end type safety.

https://www.prisma.io/docs/concepts/components/prisma-client/middleware

    const newClient =  this.$extends({
      query: {
        $allOperations({ model, operation, args, query }) {
// DO STUFF
        },
      },
    });

Could to the stuff. However it will provide a new extended instance of the client and i would need to refactor all usages that currently rely on:

@Injectable()
export class DocumentService {
  constructor(
    private prisma: PrismaService,
  ) {}

  async stuff(): Promise<document[]> {
    return this.prisma.document.findMany({
// QUERY
    });
  }

To something like:

this.prisma.newClient.document.findMany({
// QUERY
    });

Right now i made a hack that basically graps the extended client from a base class thats provides the extension:

export class PrismaService extends PrismaBasicService implements OnModuleInit {
  constructor(
    private moduleReference: ModuleRef,
    @Inject(WINSTON_MODULE_NEST_PROVIDER) localLogger: WinstonLogger, // @Inject(forwardRef(() => PrismaBasicService))
  ) {
    super(moduleReference, localLogger);
  }
  /**
   * We want to use the extended prisma service from PrismaBasicService
   * Therefore we fetch it from the module reference and overwrite the class with the extended service
   *
   */
  async onModuleInit() {
    const prismaBasic = this.moduleReference.get(PrismaBasicService, { strict: false });
    Object.assign(this, prismaBasic.extendedClient);
  }
}

Not nice. Is there a better way to do that i am currently missing?

Describe the solution you'd like

A way to make the injected prisma service to execute on the extend client if exists.

Teachability, documentation, adoption, migration strategy

Maybe a function that allows to inject the extend clients instance. Or something completely different that give the ability to make use of the extend client in a more convenient way.

What is the motivation / use case for changing the behavior?

Changing all usages of prima with the extended client is not convenient.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions