middleware
middleware copied to clipboard
either json or form validation with zod-validator
how to to support both form and json body with zValidator?
docs say that multiple validators can be used together i.e.
app.post(
'/posts/:id',
validator('param', ...),
validator('query', ...),
validator('json', ...),
(c) => {
//...
}
and
validator('form', ...),
validator('json', ...),
can even be used together. However they always through an error, thus neither form or json body is allowed.
Hi @ibqn
Currently, the Zod Validator does not support validation for either JSON or Form. But, you can write the middleware like the following or middleware to support it.
import { Hono, MiddlewareHandler } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
import { createMiddleware } from 'hono/factory'
const schema = z.object({
foo: z.string()
})
const app = new Hono()
const or = (...handlers: MiddlewareHandler[]) =>
createMiddleware(async (c, next) => {
let isValid = false
for (const handler of handlers) {
const res = await handler(c, next)
if (res && res.status === 200) {
isValid = true
break
}
}
if (!isValid) {
return c.json(
{
valid: false
},
400
)
}
})
app.post('/', or(zValidator('form', schema), zValidator('json', schema)), (c) => {
// @ts-expect-error `or` does not support infer `json`
const jsonData = c.req.valid('json')
// @ts-expect-error `or` does not support infer `form`
const formData = c.req.valid('form')
return c.json({ jsonData, formData })
})
const jsonRes = await app.request('/', {
method: 'POST',
body: JSON.stringify({ foo: 'bar' }),
headers: {
'content-type': 'application/json'
}
})
console.log(jsonRes.status) // 200
console.log(await jsonRes.json())
const form = new FormData()
form.append('foo', 'bar')
const formRes = await app.request('/', {
method: 'POST',
body: form
})
console.log(formRes.status) // 200
console.log(await formRes.json())