honojs-middleware/packages/zod-openapi
Yusuke Wada 27a0c13ae4
docs(zod-openapi): update readme (#123)
2023-08-19 10:31:58 +09:00
..
src feat: zod-openapi (#118) 2023-08-19 02:43:36 +09:00
test feat: zod-openapi (#118) 2023-08-19 02:43:36 +09:00
CHANGELOG.md Version Packages (#122) 2023-08-19 02:54:34 +09:00
README.md docs(zod-openapi): update readme (#123) 2023-08-19 10:31:58 +09:00
package.json Version Packages (#122) 2023-08-19 02:54:34 +09:00
tsconfig.json feat: zod-openapi (#118) 2023-08-19 02:43:36 +09:00

README.md

Zod OpenAPI Hono

Zod OpenAPI Hono is extending Hono to support OpenAPI. With it, you can validate values and types using Zod and generate OpenAPI Swagger documentation. This is based on Zod to OpenAPI. For details on creating schemas and defining routes, please refer to this resource.

This is not a real middleware but hosted on this monorepo.

Usage

Installation

You can install it via the npm. Should be installed with hono and zod.

npm i hono zod @hono/zod-openapi

Basic Usage

Write your application

First, define schemas with Zod:

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

const ParamsSchema = z.object({
  id: z
    .string()
    .min(3)
    .openapi({
      param: {
        name: 'id',
        in: 'path',
      },
      example: '1212121',
    }),
})

const UserSchema = z
  .object({
    id: z.string().openapi({
      example: 123,
    }),
    name: z.string().openapi({
      example: 'John Doe',
    }),
    age: z.number().openapi({
      example: 42,
    }),
  })
  .openapi('User')

Next, create routes:

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

const route = createRoute({
  method: 'get',
  path: '/users/:id',
  request: {
    params: ParamsSchema,
  },
  responses: {
    200: {
      content: {
        'application/json': {
          schema: UserSchema,
        },
      },
      description: 'Get the user',
    },
  },
})

Finally, create the App:

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

const app = new OpenAPIHono()

app.openapi(route, (c) => {
  const { id } = c.req.valid('param')
  return c.jsonT({
    id,
    age: 20,
    name: 'Ultra-man',
  })
})

// OpenAPI document will be served on /doc
app.doc('/doc', {
  openapi: '3.0.0',
  info: {
    version: '1.0.0',
    title: 'My API',
  },
})

Handling validation errors

You can handle the validation errors the following ways.

Define the schema:

const ErrorSchema = z.object({
  code: z.number().openapi({
    example: 400,
  }),
  message: z.string().openapi({
    example: 'Bad Request',
  }),
})

Add the response:

const route = createRoute({
  method: 'get',
  path: '/users/:id',
  request: {
    params: ParamsSchema,
  },
  responses: {
    400: {
      content: {
        'application/json': {
          schema: ErrorSchema,
        },
      },
      description: 'Return Error!',
    },
  },
})

Add the hook:

app.openapi(
  route,
  (c) => {
    const { id } = c.req.valid('param')
    return c.jsonT({
      id: Number(id),
      age: 20,
      name: 'Ultra-man',
    })
  },
  // Hook
  (result, c) => {
    if (!result.success) {
      return c.jsonT(
        {
          code: 400,
          message: 'Validation Error!',
        },
        400
      )
    }
  }
)

Middleware

You can use Hono's middleware as same as using Hono because Zod OpenAPI is just extending Hono.

import { prettyJSON } from 'hono/pretty-json'

//...

app.use('/doc/*', prettyJSON())

References

Authors

License

MIT