Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

either json or form validation with zod-validator #907

Open
ibqn opened this issue Dec 25, 2024 · 1 comment
Open

either json or form validation with zod-validator #907

ibqn opened this issue Dec 25, 2024 · 1 comment

Comments

@ibqn
Copy link

ibqn commented Dec 25, 2024

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.

@yusukebe
Copy link
Member

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())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants