-
Notifications
You must be signed in to change notification settings - Fork 258
fix(zod-openapi): Run validators before route middleware #1133
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
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: ea95a7d The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1133 +/- ##
=======================================
Coverage 79.53% 79.53%
=======================================
Files 77 77
Lines 2282 2282
Branches 578 578
=======================================
Hits 1815 1815
Misses 391 391
Partials 76 76
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
You can access it with the code like the following: import { z, createRoute, OpenAPIHono } from '@hono/zod-openapi'
const createUserRoute = createRoute({
method: 'post',
path: '/user',
request: {
body: {
content: {
'application/json': {
schema: z.object({
name: z.string(),
}),
},
},
},
},
middleware: [
async (c, next) => {
await next()
// @ts-expect-error not typed well
console.log(c.req.valid('json')) // You can get the validated value
},
] as const,
responses: {
200: {
description: 'foo',
},
},
})
const app = new OpenAPIHono().openapi(createUserRoute, async (c) => {
return c.json('foo')
})
export default app |
|
Hi @yusukebe, Our middleware is authenticating the request. Calling |
|
Is that possible with your PR? I don't know what code you want to implement but you may be able it with the https://github.com/honojs/middleware/tree/main/packages/zod-openapi#handling-validation-errors If you want to get more detailed help, please provide a concrete and minimal code. |
|
Sure, here's a small snippet that exemplifies what we're trying to achieve @yusukebe const userBelongsToTeam = async (c, next) => {
const email = c.get(`email`)!
const { team_id } = c.req.valid(`param`) // This fails because c.req.valid(`param`) is undefined
// check in the database if the user (identified by email) belongs to the team
const userBelongsToTeam = ...
if (!userBelongsToTeam) {
throw new HTTPException(403, { message: "You don't have access to this team" })
}
return next()
}
app.openapi(
createRoute({
method: `get`,
path: `/team/{team_id}`,
middleware: [userBelongsToTeam] as const,
...
}),
async (c) => {
// Should only reach here if the user belongs to the team
}
) |
|
Thank you for the explanation. I got it. But this will introduce a breaking change, although the test is not failing. And this is not a |
|
@yusukebe sure, i understand that. What is the reason for running the validators after the middleware? I was very surprised by that behavior. |
|
You may be surprised, but there are many people who are happy with the current specifications. For example, cases where they want to set values with |

We're using
zod-openapiand found that route middleware runs before the validators. As a result, we don't have access to validated input (likec.req.valid('param')) inside route middleware, which was somewhat surprising to us.I can imagine special use cases where one might want route middleware to run first (e.g. when dynamically adding parameters) but i would imagine that to be less common. If we really want we could make this configurable.