Middleware allows you to manipulate the parameters and interrogate the result of each query. The following example includes two middlewares:

1const prisma = new PrismaClient()
2
3prisma.$use(async (params, next) => {
4 const result = next(params);
5 return result;
6}
7
8prisma.$use(async (params, next) => {
9 return next(params);
10}
11
12// Queries here

Example use cases of middleware include:

  • Logging the time taken to perform a type of query
  • Manipulating or validating query parameters

Running order

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

  1. All logic before await next(params)
  2. All logic after await next(params)
1const prisma = new PrismaClient()
2
3prisma.$use(async (params, next) => {
4 console.log(params.args.data.title);
5 console.log("1");
6 const result = await next(params);
7 console.log("4");
8 return result;
9});
10
11prisma.$use(async (params, next) => {
12 console.log("2");
13 const result = await next(params);
14 console.log("3");
15 return result;
16});
17
18const create = await prisma.post.create({
19 data: {
20 title: "Welcome to Prisma Day 2020",
21 },
22});
23
24const create2 = await prisma.post.create({
25 data: {
26 title: "How to Prisma!",
27 },
28});

Output:

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

Prerequisites

This is a preview feature. Add the highlighted feature flag to enable distinct querying capabilities:

1generator client {
2 provider = "prisma-client-js"
3 previewFeatures = ["middlewares"]
4}

Please help us make this feature production-ready by trying it out, sharing your feedback and reporting bugs! The more and better feedback we receive, the earlier the feature can be released for production usage.

Examples

The following examples are based on a sample schema:

1generator client {
2 provider = "prisma-client-js"
3 experimentalFeatures = ["middlewares"]
4}
5
6datasource db {
7 provider = "mysql"
8 url = env("DATABASE_URL")
9}
10
11model Post {
12 authorId Int?
13 content String?
14 id Int @default(autoincrement()) @id
15 published Boolean @default(false)
16 title String
17 user User? @relation(fields: [authorId], references: [id])
18 language String?
19
20 @@index([authorId], name: "authorId")
21}
22
23model User {
24 email String @unique
25 id Int @default(autoincrement()) @id
26 name String?
27 posts Post[]
28 extendedProfile Json?
29 role Role @default(USER)
30}
31
32enum Role {
33 ADMIN
34 USER
35 MODERATOR
36}

Set the language property of each post

The following example sets the language property of each Post to the context language (taken, for example, from session state):

1const prisma = new PrismaClient();
2
3const contextLanguage = "en-us"; // Session state
4
5// Set all
6prisma.$use(async (params, next) => {
7 if (params.model == "Post") {
8 params.args.data.language = contextLanguage;
9 }
10
11 return next(params);
12});
13
14const create = await prisma.post.create({
15 data: {
16 title: "My post in English",
17 },
18});

Log the running time of each create query

The following example logs the time taken for await next(params) (executing)

1const prisma = new PrismaClient();
2
3prisma.$use(async (params, next) => {
4 const before = Date.now();
5
6 const result = await next(params);
7
8 const after = Date.now();
9
10 console.log(
11 `Query ${params.model}.${params.action} took ${after - before}ms`
12 );
13
14 return result;
15});
16
17const create = await prisma.post.create({
18 data: {
19 title: "Welcome to Prisma Day 2020",
20 },
21});
22
23const createAgain = await prisma.post.create({
24 data: {
25 title: "All about database collation",
26 },
27});
Query Post.create took 92ms
Query Post.create took 15ms
Edit this page on Github