`model`: Add custom methods to your models
Prisma Client extensions are Generally Available from versions 4.16.0 and later. They were introduced in Preview in version 4.7.0. Make sure you enable the clientExtensions
Preview feature flag if you are running on a version earlier than 4.16.0.
You can use the model
Prisma Client extensions component type to add custom methods to your models.
Possible uses for the model
component include the following:
- New operations to operate alongside existing Prisma Client operations, such as
findMany
- Encapsulated business logic
- Repetitive operations
- Model-specific utilities
Add a custom method
Use the $extends
client-level method to create an extended client. An extended client is a variant of the standard Prisma Client that is wrapped by one or more extensions. Use the model
extension component to add methods to models in your schema.
Add a custom method to a specific model
To extend a specific model in your schema, use the following structure. This example adds a method to the user
model.
const prisma = new PrismaClient().$extends({
name?: '<name>', // (optional) names the extension for error logs
model?: {
user: { ... } // in this case, we extend the `user` model
},
});
Example
The following example adds a method called signUp
to the user
model. This method creates a new user with the specified email address:
const prisma = new PrismaClient().$extends({
model: {
user: {
async signUp(email: string) {
await prisma.user.create({ data: { email } })
},
},
},
})
You would call signUp
in your application as follows:
const user = await prisma.user.signUp('john@prisma.io')
Add a custom method to all models in your schema
To extend all models in your schema, use the following structure:
const prisma = new PrismaClient().$extends({
name?: '<name>', // `name` is an optional field that you can use to name the extension for error logs
model?: {
$allModels: { ... }
},
})
Example
The following example adds an exists
method to all models.
const prisma = new PrismaClient().$extends({
model: {
$allModels: {
async exists<T>(
this: T,
where: Prisma.Args<T, 'findFirst'>['where']
): Promise<boolean> {
// Get the current model at runtime
const context = Prisma.getExtensionContext(this)
const result = await (context as any).findFirst({ where })
return result !== null
},
},
},
})
You would call exists
in your application as follows:
// `exists` method available on all models
await prisma.user.exists({ name: 'Alice' })
await prisma.post.exists({
OR: [{ title: { contains: 'Prisma' } }, { content: { contains: 'Prisma' } }],
})
Call a custom method from another custom method
You can call a custom method from another custom method, if the two methods are declared on the same model. For example, you can call a custom method on the user
model from another custom method on the user
model. It does not matter if the two methods are declared in the same extension or in different extensions.
To do so, use Prisma.getExtensionContext(this).methodName
. Note that you cannot use prisma.user.methodName
. This is because prisma
is not extended yet, and therefore does not contain the new method.
For example:
const prisma = new PrismaClient().$extends({
model: {
user: {
firstMethod() {
...
},
secondMethod() {
Prisma.getExtensionContext(this).firstMethod()
}
}
}
})
Get the current model name at runtime
This feature is available from version 4.9.0.
You can get the name of the current model at runtime with Prisma.getExtensionContext(this).$name
. You might use this to write out the model name to a log, to send the name to another service, or to branch your code based on the model.
For example:
// `context` refers to the current model
const context = Prisma.getExtensionContext(this)
// `context.name` returns the name of the current model
console.log(context.name)
// Usage
await(context as any).findFirst({ args })
Refer to Add a custom method to all models in your schema for a concrete example for retrieving the current model name at runtime.
Advanced type safety: type utilities for defining generic extensions
You can improve the type-safety of model
components in your shared extensions with type utilities.