#How to use Zod validation for database writes?
4 messages · Page 1 of 1 (latest)
Hi @timid hinge. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Based on the knowledge sources, there isn't a direct built-in way to use Zod validation for database writes in Convex, but there are several approaches you can take.
Approaches for Zod validation with database writes
According to the article on using Zod with TypeScript, here are the recommended approaches:
-
Wrap your database operations: You can wrap
ctx.dbin mutations to validate data before writing it to the database. This ensures that new data being written follows your Zod schema. -
Validate in your mutation handlers: You can manually validate data using Zod schemas before inserting it into the database.
-
Use
zodOutputToConvex: This function can convert your Zod validators into Convex types that can be used for table definitions, though with some limitations.
The author of the article recommends:
"I'd use Zod validation for server arguments, and trust that the server code will write valid data. If it's very important, I'd consolidates those writes to a function where I manually validate the data & business logic before writing it." Zod with TypeScript for Server-side Validation
Important considerations
When using Zod for database validation:
- If a developer edits data in the dashboard or uploads data via the CLI, your Zod validators won't run
- For more specific types (like
z.tuple), you might want to use Zod on the read side to validate the structure - You can use
zodOutputToConvexto define table schemas from Zod types, but validation isn't guaranteed at the database level
Example approach
Here's how you might implement validation before writing to the database:
// In your mutation function
export const createUser = zMutation({
args: { name: z.string(), email: z.string().email() },
handler: async (ctx, args) => {
// The args are already validated by zMutation
// You can do additional validation if needed
const userSchema = z.object({
name: z.string(),
email: z.string().email()
});
// Validate the data before inserting
const validatedUser = userSchema.parse(args);
// Now insert the validated data
return await ctx.db.insert("users", validatedUser);
},
});