Prisma-client-js: Prisma Client triggers or lifecycle events

Created on 14 Apr 2020  路  5Comments  路  Source: prisma/prisma-client-js

Problem

Prisma Client lacks observable lifecycle events or database triggers. Popular alternatives to prisma (and even databases themselves) have these as mature and well documented features.
For example, Hasura and Sequelize. Having triggers / events is important because it opens up huge possibilities with the prisma-nexus plugin. The goal would be to leverage the code reduction and API consistency that nexus allows without having to tap into a custom mutation for seemingly every case but the most absolutely simplified. Not to mention data validation.

Solution

Prisma Client should have a way to define functions before and after crud operations. Here is an example that I thought of which would be pretty common. The Sequelize link I posted above also has plenty of examples and concepts, basically an instruction guide on what to include.

prisma = new PrismaClient();
prisma.setTriggers(prisma => ({
  beforeOrderCreate: async (args: OrderCreateArgs): Promise<OrderCreateArgs> => {
  const grandTotal = calcGrandTotal(args.data.lineItems.create);
  // Error can be thrown here
  await processPayment(grandTotal, args.data.user.connect.id);
  return {
    ...args, 
    { 
      data: {
        ...args.data, 
        grandTotal 
      }
    }
  })
  afterOrderCreate: async (order: Order): Promise<void> => {
    const user = await prisma.order.findOne({ where: { id: order.id } }).user();
    if (user.acceptsEmail) {
       await sendEmailToCustomer(order.id, order.grandTotal, user.name);
    }
  },
  afterOrderUpdate: async (newOrder: Order, oldOrder: Order): Promise<void> => {
    if (newOrder.grandTotal !== oldOrder.grandTotal) {
      await prisma.creditNote.create({
        data: {
          amount: newOrder.grandTotal - oldOrder.grandTotal,
          order: { connect: { id: newOrder.id }
        }
      }
    }
  }
}))

Alternatives

Additional context

kinfeature

Most helpful comment

@chareice I think you can use a Prisma middleware for this now: https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/middleware

All 5 comments

Thanks a lot for raising this issue. This is definitely something we've thought about before (e.g. here https://github.com/prisma/specs/issues/444).

I'm also looking for this feature. I need to process the data on the backend side in some sort of queue, where I'd like to watch for status changes of entities and perform some operations.

I could technically do it just after I perform updates, but the goal of my architecture is to make processing fully independent from CRUD implementation

Any Progress? It's Important.

@chareice I think you can use a Prisma middleware for this now: https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/middleware

This is covered by middlewares. If your use-case might not be supported, please create a separate issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

macrozone picture macrozone  路  4Comments

FluorescentHallucinogen picture FluorescentHallucinogen  路  3Comments

AhmedElywa picture AhmedElywa  路  4Comments

julien1619 picture julien1619  路  3Comments

MichalLytek picture MichalLytek  路  3Comments