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

Error with Hono, Swagger UI, and Zod OpenAPI Integration: Missing Parameter Data for Query Parameter with Refine and Transform #560

Closed
mandado opened this issue Jun 6, 2024 · 7 comments · Fixed by #582

Comments

@mandado
Copy link

mandado commented Jun 6, 2024

I encountered an issue with Hono, alongside the Swagger UI package and Zod OpenAPI.

The problem occurs when I pass a Zod schema to the query parameter of a request that contains a refine and a transform together.

It throws the following error and does not support typing.

Code: https://gist.github.com/mandado/420a0c72caae9438bf11fcca55815324

Response:

{
  "message": "Missing parameter data, please specify `name` and other OpenAPI parameter props using the `param` field of `ZodSchema.openapi`",
  "data": {
    "missingField": "name",
    "location": "query",
    "route": "get /my-user"
  }
}

Type error:

image
image

@yusukebe
Copy link
Member

yusukebe commented Jun 9, 2024

Hi @mandado

In this case, you have to write the following to get it to work:

const test = createRoute({
  path: '/my-user',
  method: 'get',
  summary: 'Get a single user',
  request: {
    query: z.object({
      name: z
        .string()
        .optional()
        .refine(
          (name) => {
            return !name?.includes('forbidden')
          },
          {
            message: 'name is invalid'
          }
        )
    })
  },
  responses: {
    200: {
      description: 'Object with user data.',
      content: {
        'application/json': {
          schema: z.object({})
        }
      }
    },
    204: {
      description: 'No content - successful operation'
    }
  }
})

@mandado
Copy link
Author

mandado commented Jun 11, 2024

Hi @yusukebe, I don't understand the differences in the responses. What I know is that I can't use the "refine" and "transform" together because this breaks the app.

@yusukebe
Copy link
Member

yusukebe commented Jun 14, 2024

@mandado

What version of @hono/zod-openapi do you use?

Btw, using both .refine() and .transform() for the object is not supported in @asteasolutions/zod-to-openapi, which is used in @hono/zod-openapi.

import { OpenAPIRegistry } from '@asteasolutions/zod-to-openapi'

const user = z
  .object({ name: z.string(), age: z.string() })
  .refine((val) => val.name || val.age, {
    message: 'name or age required',
    path: ['name', 'age']
  })
  .transform((data) => data) // <--- Not support

const registry = new OpenAPIRegistry()

registry.registerPath({
  method: 'get',
  path: '/users/{id}',
  summary: 'Get a single user',
  request: {
    params: user, // <-- error
    query: user, // <-- error
    body: {
      content: {
        'application/json': {
          schema: user
        }
      }
    }
  },
  responses: {}
})

@mandado
Copy link
Author

mandado commented Jun 14, 2024

@yusukebe version ^0.14.0

@yusukebe
Copy link
Member

@mandado

Thanks. Can you update it to 0.14.3? and try the following code?

import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi'

const app = new OpenAPIHono()

const test = createRoute({
  path: '/my-user',
  method: 'get',
  summary: 'Get a single user',
  request: {
    query: z // <--- Type Error
      .object({
        name: z.string().optional()
      })
      .refine(
        (data) => {
          return !data.name?.includes('forbidden')
        },
        {
          message: 'name is invalid'
        }
      )
      .transform((data) => {
        return data
      })
  },
  responses: {
    200: {
      description: 'Object with user data.',
      content: {
        'application/json': {
          schema: z.object({})
        }
      }
    },
    204: {
      description: 'No content - successful operation'
    }
  }
})

app.openapi(test, (c) => {
  const { name } = c.req.valid('query') // <--- Type Error
  return c.json({
    name,
    age: 20
  })
})

// ...

The error message will be the following:

{"success":false,"error":{"issues":[{"code":"custom","message":"name is invalid","path":[]}],"name":"ZodError"}}

This may be what you expected.

But, it throws type errors yet. I think this is an issue related to asteasolutions/zod-to-openapi#238

@mandado
Copy link
Author

mandado commented Jun 14, 2024

Yes! Works well! This is what I'm expecting thank you so much!. resting only the errror type from asteasolutions/zod-to-openapi#238

@yusukebe
Copy link
Member

Hey @mandado

Can you try @hono/[email protected]? which includes the new version of @asteasolutions/zod-to-openapi?

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

Successfully merging a pull request may close this issue.

2 participants