feat(zod-openapi): Add 'middleware' property for route (#435)

* feat: Add 'middlewares' property for route

* fix: Rename `middlewares` to `middleware`

* fix: Update README.md

* fix: Fix changeset
pull/447/head
Roman Nabukhotnyi 2024-04-11 13:16:12 +03:00 committed by GitHub
parent 56b11664ec
commit 4660092b9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 65 additions and 2 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/zod-openapi': minor
---
Add 'middleware' property for route

View File

@ -270,6 +270,32 @@ app.use(route.getRoutingPath(), prettyJSON(), cache({ cacheName: 'my-cache' }))
app.openapi(route, handler)
```
Or you can use the `middleware` property in the route definition.
```ts
const route = createRoute({
method: 'get',
path: '/users/{id}',
request: {
params: ParamsSchema,
},
middleware: [
prettyJSON(),
cache({ cacheName: 'my-cache' })
],
responses: {
200: {
content: {
'application/json': {
schema: UserSchema,
},
},
description: 'Retrieve the user',
},
},
})
```
### RPC Mode
Zod OpenAPI Hono supports Hono's RPC mode. You can define types for the Hono Client as follows:

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import type {
ResponseConfig,
RouteConfig,
RouteConfig as RouteConfigBase,
ZodContentObject,
ZodMediaTypeObject,
ZodRequestBody,
@ -32,6 +32,10 @@ import { mergePath } from 'hono/utils/url'
import type { AnyZodObject, ZodSchema, ZodError } from 'zod'
import { z, ZodType } from 'zod'
type RouteConfig = RouteConfigBase & {
middleware?: MiddlewareHandler | MiddlewareHandler[]
}
type RequestTypes = {
body?: ZodRequestBody
params?: AnyZodObject
@ -310,7 +314,9 @@ export class OpenAPIHono<
}
}
this.on([route.method], route.path.replaceAll(/\/{(.+?)}/g, '/:$1'), ...validators, handler)
const middleware = route.middleware ? (Array.isArray(route.middleware) ? route.middleware : [route.middleware]) : []
this.on([route.method], route.path.replaceAll(/\/{(.+?)}/g, '/:$1'), ...middleware, ...validators, handler)
return this
}

View File

@ -1361,3 +1361,29 @@ describe('Handle "Conflicting names for parameter"', () => {
})
})
})
describe('Middleware', () => {
const app = new OpenAPIHono()
app.openapi(
createRoute({
method: 'get',
path: '/books',
middleware: [(c, next) => {
c.header('x-foo', 'bar')
return next()
}],
responses: {
200: {
description: 'response',
},
},
}),
(c) => c.text('foo')
)
it('Should have the header set by the middleware', async () => {
const res = await app.request('/books')
expect(res.status).toBe(200)
expect(res.headers.get('x-foo')).toBe('bar')
})
})