middleware
middleware copied to clipboard
[zod-openapi] MaybePromise response type issue
All my routes are broken because of this change #522. Are any changes necessary?
hono : 4.3.7
zod : 3.23.8
zod-openapi : 0.12.1
(working good 0.11.1
)
Argument of type '(c: Context<Env, "/health", {}>) => Response & TypedResponse<"OK", 200, "json">' is not assignable to parameter of type 'Handler<Env, "/health", {}, MaybePromise<TypedResponse<never, 200, "json">>>'.
Type 'Response & TypedResponse<"OK", 200, "json">' is not assignable to type 'MaybePromise<TypedResponse<never, 200, "json">>'.
Type 'Response & TypedResponse<"OK", 200, "json">' is not assignable to type 'TypedResponse<never, 200, "json">'.
Types of property 'data' are incompatible.
Type 'string' is not assignable to type 'never'.ts(2345)
export const healthCheck = createRoute({
method: 'get',
path: '/health',
summary: 'Health check',
description: 'Health check',
responses: {
200: {
description: 'Successful response',
content: {
'application/json': {
schema: { type: 'string' },
},
},
},
},
500: serverErrorSchema,
tags: ['health'],
});
health.openapi(healthCheck, (c) => {
return c.json('OK', 200);
});
When multiple response definitions are specified for an API, it seems to result in an error if there are differences in the schema.
ok
const app = new OpenAPIHono()
.openapi(createRoute({
method: 'get',
path: '/users',
responses: {
200: {
description: 'users',
content: {
'application/json': {
schema: z.array(
z.object({
id: z.string(),
name: z.string(),
age: z.number(),
})
),
},
},
},
204: {
description: 'internal error',
content: {
'application/json': {
schema: z.array(
z.object({
id: z.string(),
name: z.string(),
age: z.number(),
})
),
},
},
},
},
}),
async (c) => {
const users = await getUsersQueryToDatabase()
if (users.length === 0) {
return c.json([], 400)
}
return c.json(users)
})
/* This code is also OK.
204: {
description: 'internal error',
},
*/
ng
const app = new OpenAPIHono()
.openapi(createRoute({
method: 'get',
path: '/users',
responses: {
200: {
description: 'users',
content: {
'application/json': {
schema: z.array(
z.object({
id: z.string(),
name: z.string(),
age: z.number(),
})
),
},
},
},
500: {
description: 'internal error',
content: {
'application/json': {
schema: z.array(
z.object({
code: z.number(),
message: z.string(),
})
),
},
},
},
},
}),
async (c) => {
const users = await getUsersQueryToDatabase()
if (users.length === 0) {
return c.json({ code: 500, message: 'internal error'}, 500)
}
return c.json(users)
})
I fixed, Adding a response without content.
example
const app = new OpenAPIHono()
.openapi(createRoute({
method: 'get',
path: '/users',
responses: {
200: {
description: 'users',
content: {
'application/json': {
schema: z.array(
z.object({
id: z.string(),
name: z.string(),
age: z.number(),
})
),
},
},
},
// adding this response
204: {
description: 'no content',
},
500: {
description: 'internal server error',
content: {
'application/json': {
schema: z.array(
z.object({
id: z.string(),
name: z.string(),
age: z.number(),
})
),
},
},
},
},
}),
async (c) => {
const users = await getUsersQueryToDatabase()
if (users.length === 0) {
return c.json([], 400)
}
return c.json(users)
})
But it is a temporary workaround.
Hi @Jayllyz
How about using z.string()
instead of { type: 'string' }
?
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi'
const app = new OpenAPIHono()
export const healthCheck = createRoute({
method: 'get',
path: '/health',
summary: 'Health check',
description: 'Health check',
responses: {
200: {
description: 'Successful response',
content: {
'application/json': {
schema: z.string() // <===
}
}
}
},
tags: ['health']
})
app.openapi(healthCheck, (c) => {
return c.json('foo', 200)
})
export default app
Hi @yusukebe it worked, thanks!