Note: Middleware is a stable feature as of version 2.5.0.

Middleware allows you to perform an action before or after each query runs. Use the prisma.$use method to add middleware:

script.ts
1const prisma = new PrismaClient()
2
3// Middleware 1
4prisma.$use(async (params, next) => {
5 // Manipulate params here
6 const result = next(params);
7 // See results here
8 return result;
9}
10
11// Middleware 2
12prisma.$use(async (params, next) => {
13 // Manipulate params here
14 const result = next(params);
15 // See results here
16 return result;
17}
18
19// Queries here

Use cases for middleware include:

Examples

Reference

params accepts the following type:

export type MiddlewareParams = {
model?: string
action: Action
args: any
dataPath: string[]
runInTransaction: boolean
}

Example:

{
args: { where: { id: 15 } },
dataPath: [ 'select', 'author', 'select', 'posts' ],
runInTransaction: false,
action: 'findMany',
model: 'Post'
}

Parameter descriptions:

ParameterDescription
actionThe query type - for example, create or findMany. See CRUD reference for all available queries.
argsArguments that were passed into the query - for example, where, data, or orderBy. See CRUD reference for all available arguments.
dataPathPopulated if you use the fluent API.
modelThe name of the mode - for example, Post or User.
runInTransactionReturns true if the query ran in the context of a transaction.

Running order

If you have multiple middlewares, the running order for each separate query is:

  1. All logic before await next(params)
  2. All logic after await next(params)
const prisma = new PrismaClient()
prisma.$use(async (params, next) => {
console.log(params.args.data.title)
console.log('1')
const result = await next(params)
console.log('4')
return result
})
prisma.$use(async (params, next) => {
console.log('2')
const result = await next(params)
console.log('3')
return result
})
const create = await prisma.post.create({
data: {
title: 'Welcome to Prisma Day 2020',
},
})
const create2 = await prisma.post.create({
data: {
title: 'How to Prisma!',
},
})

Output:

Welcome to Prisma Day 2020
1
2
3
4
How to Prisma!
1
2
3
4

Performance and appropriate use cases

Middleware executes for every query, which means that overuse has the potential to negatively impact performance. To avoid adding performance overheads:

  • Check the params.model and params.action properties early in your middleware to avoid running logic unnecessarily:

    prisma.$use(async (params, next) => {
    if (params.model == 'Post' && params.action == 'delete') {
    // Logic only runs for delete action and Post model
    }
    return next(params)
    })
  • Consider whether middleware is the appropriate solution for your scenario. For example:

    • If you need to populate a field, can you use the @default attribute?
    • If you need to set the value of a DateTime field, can you use the now() function or the @updatedAt attribute?
    • If you need to perform more complex validation, can you use a CHECK constraint in the database itself?
Edit this page on GitHub