跳到主要內容

自定義驗證

你可以透過以下任一方式為 Prisma Client 查詢的使用者輸入新增執行時驗證:

你可以使用任何你喜歡的驗證庫。Node.js 生態系統提供了許多高質量、易於使用的驗證庫供你選擇,包括:joivalidator.jsYupZodSuperstruct

使用 Prisma Client 擴充套件進行輸入驗證

此示例展示瞭如何使用 Zod schema 在建立和更新值時新增執行時驗證,以檢查傳遞給 Prisma Client 的資料是否有效。

警告

查詢擴充套件目前不適用於巢狀操作。在此示例中,驗證僅在傳遞給 prisma.product.create() 等方法的頂級資料物件上執行。以這種方式實現的驗證不會自動運行於巢狀寫入

import { PrismaClient, Prisma } from '@prisma/client'
import { z } from 'zod'

/**
* Zod schema
*/
export const ProductCreateInput = z.object({
slug: z
.string()
.max(100)
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),
name: z.string().max(100),
description: z.string().max(1000),
price: z
.instanceof(Prisma.Decimal)
.refine((price) => price.gte('0.01') && price.lt('1000000.00')),
}) satisfies z.Schema<Prisma.ProductUncheckedCreateInput>

/**
* Prisma Client Extension
*/
const prisma = new PrismaClient().$extends({
query: {
product: {
create({ args, query }) {
args.data = ProductCreateInput.parse(args.data)
return query(args)
},
update({ args, query }) {
args.data = ProductCreateInput.partial().parse(args.data)
return query(args)
},
updateMany({ args, query }) {
args.data = ProductCreateInput.partial().parse(args.data)
return query(args)
},
upsert({ args, query }) {
args.create = ProductCreateInput.parse(args.create)
args.update = ProductCreateInput.partial().parse(args.update)
return query(args)
},
},
},
})

async function main() {
/**
* Example usage
*/
// Valid product
const product = await prisma.product.create({
data: {
slug: 'example-product',
name: 'Example Product',
description: 'Lorem ipsum dolor sit amet',
price: new Prisma.Decimal('10.95'),
},
})

// Invalid product
try {
await prisma.product.create({
data: {
slug: 'invalid-product',
name: 'Invalid Product',
description: 'Lorem ipsum dolor sit amet',
price: new Prisma.Decimal('-1.00'),
},
})
} catch (err: any) {
console.log(err?.cause?.issues)
}
}

main()

上述示例使用 Zod schema 在記錄寫入資料庫之前,在執行時驗證和解析查詢中提供的資料。

使用自定義驗證函式進行輸入驗證

這是一個使用 Superstruct 驗證註冊新使用者所需資料是否正確的示例

import { PrismaClient, Prisma, User } from '@prisma/client'
import { assert, object, string, size, refine } from 'superstruct'
import isEmail from 'isemail'

const prisma = new PrismaClient()

// Runtime validation
const Signup = object({
// string and a valid email address
email: refine(string(), 'email', (v) => isEmail.validate(v)),
// password is between 7 and 30 characters long
password: size(string(), 7, 30),
// first name is between 2 and 50 characters long
firstName: size(string(), 2, 50),
// last name is between 2 and 50 characters long
lastName: size(string(), 2, 50),
})

type Signup = Omit<Prisma.UserCreateArgs['data'], 'id'>

// Signup function
async function signup(input: Signup): Promise<User> {
// Assert that input conforms to Signup, throwing with a helpful
// error message if input is invalid.
assert(input, Signup)
return prisma.user.create({
data: input.user,
})
}

上述示例展示瞭如何建立一個自定義的型別安全的 signup 函式,以確保在建立使用者之前輸入是有效的。

深入瞭解

  • 瞭解如何使用 Prisma Client 擴充套件為你的查詢新增輸入驗證 — 示例
  • 瞭解如何透過將 signup 函式移動到自定義模型中來更好地組織你的程式碼。
  • 有一個懸而未決的功能請求,旨在將使用者驗證內建到 Prisma Client 中。如果你希望看到它實現,請務必投票支援該問題並分享你的用例!
© . This site is unofficial and not affiliated with Prisma Data, Inc.