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) 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 ### RPC Mode
Zod OpenAPI Hono supports Hono's RPC mode. You can define types for the Hono Client as follows: 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 */ /* eslint-disable @typescript-eslint/no-unused-vars */
import type { import type {
ResponseConfig, ResponseConfig,
RouteConfig, RouteConfig as RouteConfigBase,
ZodContentObject, ZodContentObject,
ZodMediaTypeObject, ZodMediaTypeObject,
ZodRequestBody, ZodRequestBody,
@ -32,6 +32,10 @@ import { mergePath } from 'hono/utils/url'
import type { AnyZodObject, ZodSchema, ZodError } from 'zod' import type { AnyZodObject, ZodSchema, ZodError } from 'zod'
import { z, ZodType } from 'zod' import { z, ZodType } from 'zod'
type RouteConfig = RouteConfigBase & {
middleware?: MiddlewareHandler | MiddlewareHandler[]
}
type RequestTypes = { type RequestTypes = {
body?: ZodRequestBody body?: ZodRequestBody
params?: AnyZodObject 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 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')
})
})