Validate Data
When you receive data from user on your server, you must validate them. By validate, we mean that the shape of the received data must match the expected shape. It's important because you can't trust user input.
readBody
is not a validation. You must validate the data before using them.Utilities for Validation
h3 provide some utilities to help you to handle data validation. You will be able to validate:
- query with
getValidatedQuery
- params with
getValidatedRouterParams
. - body with
readValidatedBody
To validate data, you can use any validation library you want. h3 doesn't provide any validation library like Zod, joi or myzod.
Let's see how to validate data with Zod.
For the following examples, we will use the following schema:
import { z } from "zod";
const userSchema = z.object({
name: z.string().min(3).max(20),
age: z.number({ coerce: true }).positive().int(),
});
Validate Query
You can use getValidatedQuery
to validate query and get the result, as a replacement of getQuery
:
import { defineEventHandler, getValidatedQuery } from "h3";
app.use(
defineEventHandler(async (event) => {
const query = await getValidatedQuery(event, userSchema.parse);
return `Hello ${query.name}! You are ${query.age} years old.`;
}),
);
safeParse
instead of parse
to get a partial query object and to not throw an error if the query is invalid.If you send a valid request like /?name=John&age=42
to this event handler, you will get a response like this:
Hello John! You are 42 years old.
If you send an invalid request and the validation fails, h3 will throw a 400 Validation Error
error. In the data of the error, you will find the validation errors you can use on your client to display a nice error message to your user.
Validate Params
You can use getValidatedRouterParams
to validate params and get the result, as a replacement of getRouterParams
:
import { defineEventHandler, getValidatedRouterParams } from "h3";
router.use(
// You must use a router to use params
"/hello/:name/:age",
defineEventHandler(async (event) => {
const params = await getValidatedRouterParams(event, userSchema.parse);
return `Hello ${params.name}! You are ${params.age} years old!`;
}),
);
safeParse
instead of parse
to get a partial params object and to not throw an error if the params is invalid.If you send a valid request like /hello/John/42
to this event handler, you will get a response like this:
Hello John! You are 42 years old.
If you send an invalid request and the validation fails, h3 will throw a 400 Validation Error
error. In the data of the error, you will find the validation errors you can use on your client to display a nice error message to your user.
Validate Body
You can use readValidatedBody
to validate body and get the result, as a replacement of readBody
:
import { defineEventHandler, readValidatedBody } from "h3";
app.use(
defineEventHandler(async (event) => {
const body = await readValidatedBody(event, userSchema.parse);
return `Hello ${body.name}! You are ${body.age} years old.`;
}),
);
safeParse
instead of parse
to get a partial body object and to not throw an error if the body is invalid.If you send a valid POST request to this event handler, you will get a response like this:
Hello John! You are 42 years old.
If you send an invalid request and the validation fails, h3 will throw a 400 Validation Error
error. In the data of the error, you will find the validation errors you can use on your client to display a nice error message to your user.