Chapter 9
Validation
Validate incoming data before handlers use it.
Validation
Validation keeps route handlers small and protects them from unexpected input. Hono's validator() function runs as middleware before the handler.
import { validator } from 'hono/validator'
Validate JSON
The validator callback receives the parsed value for a target such as json, form, query, header, cookie, or param.
app.post(
'/api/chapters',
validator('json', (value, c) => {
const title = value.title
if (typeof title !== 'string' || title.trim() === '') {
return c.json({ error: 'Title is required' }, 400)
}
return {
title: title.trim(),
}
}),
(c) => {
const chapter = c.req.valid('json')
return c.json({ chapter }, 201)
}
)
If the validator returns a response, Hono stops and sends that response. If it returns data, the handler can read it with c.req.valid().
Validate forms
The same pattern works for form submissions.
app.post(
'/subscribe',
validator('form', (value, c) => {
const email = value.email
if (typeof email !== 'string' || !email.includes('@')) {
return c.text('A valid email is required', 400)
}
return { email }
}),
(c) => {
const { email } = c.req.valid('form')
return c.text(`Subscribed ${email}`)
}
)
For larger apps, you can pair Hono validation with schema libraries. The important habit is the same: validate at the route boundary, then keep the handler focused on application behavior.