Recipes
Authentication
Generally you just need to follow one of the Authentication guides here, depending on the type of authentication you're using.
Bearer Auth Example
const app = new Hono().get(
'/example',
openApi({
responses: {
200: z.object({}),
},
security: [{ bearerAuth: [] }],
}),
async (c) => {
return c.json({}, 200);
},
);
createOpenApiDocument(app, {
info: {
title: 'Some API',
version: '0.0.1',
},
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
},
},
},
// if you use bearer auth in every endpoint, you can add
// this here instead of adding `security` to every route:
// security: [{ bearerAuth: [] }],
});Reusing Common Fields
Adding the same fields to various routes over and over can be a bit tedious. You can create your own typesafe wrapper, which will provide the fields shared by multiple endpoints. For example, if a lot of your endpoints require a security field and a tag, you can create a function like this:
import { defineOpenApiOperation } from 'hono-zod-openapi';
import type {
HonoOpenApiOperation,
HonoOpenApiRequestSchemas,
HonoOpenApiResponses,
} from 'hono-zod-openapi';
const taggedAuthRoute = <
Req extends HonoOpenApiRequestSchemas,
Res extends HonoOpenApiResponses,
>(
doc: HonoOpenApiOperation<Req, Res>,
) => {
return defineOpenApiOperation({
...doc,
tags: ['MyTag'],
security: [{ apiKey: [] }],
});
};And use it with the openApi middleware:
openApi(
taggedAuthRoute({
request: {
json: z.object({ field: z.number() }),
},
}),
);Custom Error Handling
In general, hono-zod-openapi stays away from error handling and delegates it fully to zod-validator. zod-validator, however, accepts a third argument hook, using which you can intercept the validation result for every usage of the middleware. There is no direct equivalent for that in hono-zod-openapi, as in my experience it made more sense to create a custom middleware that wraps zod-validator and handles the errors in a unified way.
That approach is supported. You can create your own openApi middleware using createOpenApiMiddleware - it's used internally to create the openApi exported by the library.
Example with zod-validation-error
Using the excellent zod-validation-error library that translates ZodErrors into user-friendly strings:
import { zValidator } from '@hono/zod-validator';
import { HTTPException } from 'hono/http-exception';
import { createOpenApiMiddleware } from 'hono-zod-openapi';
import { fromZodError } from 'zod-validation-error';
import * as z from 'zod';
// works exactly the same way as `openApi` exported by `hono-zod-openapi`
export const openApi = createOpenApiMiddleware((target, schema) =>
zValidator(target, schema, (result, c) => {
if (!result.success) {
const validationError = fromZodError(result.error, {
includePath: false,
});
// you can handle that in `new Hono().onError()` or just use e.g. `c.json()` directly instead
throw new HTTPException(400, {
message: validationError.message,
cause: validationError,
});
}
}),
);If there is a need for handling errors on a case-by-case basis - create an issue and let's try to find a sensible solution for that!