OpenAPI document generation methods supporting both OpenAPI 3.0 and 3.1 specifications with configurable generation options and automatic endpoint creation.
Generate OpenAPI 3.0 specification documents from registered routes and schemas.
/**
* Generate OpenAPI 3.0 document from registered routes
* @param objectConfig - OpenAPI document configuration (info, servers, etc.)
* @param generatorConfig - Optional generator configuration options
* @returns Complete OpenAPI 3.0 document object
*/
getOpenAPIDocument(
objectConfig: OpenAPIObjectConfig,
generatorConfig?: OpenAPIGeneratorOptions
): OpenAPIObject;Usage Examples:
import { OpenAPIHono } from "@hono/zod-openapi";
const app = new OpenAPIHono();
// Register some routes first
app.openapi(userRoutes, userHandler);
app.openapi(postRoutes, postHandler);
// Generate OpenAPI 3.0 document
const document = app.getOpenAPIDocument({
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
description: 'A comprehensive API for managing users and posts',
},
servers: [
{
url: 'https://api.example.com',
description: 'Production server',
},
{
url: 'https://staging-api.example.com',
description: 'Staging server',
},
],
});
// Use the document
console.log(JSON.stringify(document, null, 2));Generate OpenAPI 3.1 specification documents with enhanced JSON Schema support.
/**
* Generate OpenAPI 3.1 document from registered routes
* @param objectConfig - OpenAPI document configuration (info, servers, etc.)
* @param generatorConfig - Optional generator configuration options
* @returns Complete OpenAPI 3.1 document object
*/
getOpenAPI31Document(
objectConfig: OpenAPIObjectConfig,
generatorConfig?: OpenAPIGeneratorOptions
): OpenAPIV31Object;Usage Examples:
// Generate OpenAPI 3.1 document with enhanced features
const document31 = app.getOpenAPI31Document(
{
openapi: '3.1.0',
info: {
version: '2.0.0',
title: 'My API v2',
description: 'Enhanced API with OpenAPI 3.1 features',
},
},
{
// Generator options for 3.1
unionPreferredType: 'oneOf',
unionOneOfDefaultDifferentiationStrategy: 'discriminator',
}
);Create HTTP endpoints that serve OpenAPI 3.0 documentation as JSON.
/**
* Create GET endpoint serving OpenAPI 3.0 document
* @param path - Path for the documentation endpoint
* @param configureObject - Document config or function returning config
* @param configureGenerator - Generator config or function returning config
* @returns OpenAPIHono instance for chaining
*/
doc<P extends string>(
path: P,
configureObject: OpenAPIObjectConfigure<E, P>,
configureGenerator?: OpenAPIGeneratorConfigure<E, P>
): OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath>;Usage Examples:
// Static configuration
app.doc('/openapi.json', {
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
},
});
// Dynamic configuration using context
app.doc('/openapi.json', (c) => ({
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
},
servers: [
{
url: new URL(c.req.url).origin,
description: 'Current environment',
},
],
}));
// With generator configuration
app.doc(
'/openapi.json',
{
openapi: '3.0.0',
info: { version: '1.0.0', title: 'My API' },
},
{
// Custom generator options
defaultSuccessResponseCode: 200,
}
);
// Context-aware generator config
app.doc(
'/openapi.json',
baseConfig,
(c) => ({
// Generator options based on request context
defaultSuccessResponseCode: c.req.header('prefer-201') ? 201 : 200,
})
);Create HTTP endpoints that serve OpenAPI 3.1 documentation as JSON.
/**
* Create GET endpoint serving OpenAPI 3.1 document
* @param path - Path for the documentation endpoint
* @param configureObject - Document config or function returning config
* @param configureGenerator - Generator config or function returning config
* @returns OpenAPIHono instance for chaining
*/
doc31<P extends string>(
path: P,
configureObject: OpenAPIObjectConfigure<E, P>,
configureGenerator?: OpenAPIGeneratorConfigure<E, P>
): OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath>;Usage Examples:
// OpenAPI 3.1 endpoint
app.doc31('/openapi31.json', {
openapi: '3.1.0',
info: {
version: '1.0.0',
title: 'My API',
},
});
// With 3.1-specific generator options
app.doc31(
'/openapi31.json',
{
openapi: '3.1.0',
info: { version: '1.0.0', title: 'My API' },
},
{
unionPreferredType: 'oneOf',
unionOneOfDefaultDifferentiationStrategy: 'discriminator',
}
);Configuration types for OpenAPI document and generator options.
/**
* OpenAPI document configuration (static or dynamic)
*/
type OpenAPIObjectConfigure<E extends Env, P extends string> =
| OpenAPIObjectConfig
| ((context: Context<E, P>) => OpenAPIObjectConfig);
/**
* Generator configuration (static or dynamic)
*/
type OpenAPIGeneratorConfigure<E extends Env, P extends string> =
| OpenAPIGeneratorOptions
| ((context: Context<E, P>) => OpenAPIGeneratorOptions);
/**
* OpenAPI document configuration object
*/
interface OpenAPIObjectConfig {
openapi: '3.0.0' | '3.1.0';
info: {
title: string;
version: string;
description?: string;
termsOfService?: string;
contact?: {
name?: string;
url?: string;
email?: string;
};
license?: {
name: string;
url?: string;
};
};
servers?: Array<{
url: string;
description?: string;
variables?: Record<string, {
enum?: string[];
default: string;
description?: string;
}>;
}>;
externalDocs?: {
description?: string;
url: string;
};
}
/**
* Generator options for customizing document generation
*/
interface OpenAPIGeneratorOptions {
/** Default success response code when not specified */
defaultSuccessResponseCode?: number;
/** Preferred union type representation */
unionPreferredType?: 'oneOf' | 'anyOf';
/** Strategy for differentiating oneOf unions */
unionOneOfDefaultDifferentiationStrategy?: 'discriminator' | 'none';
}Common patterns for setting up comprehensive API documentation.
Usage Examples:
// Complete documentation setup
const app = new OpenAPIHono();
// Register all routes
app.openapi(getUserRoute, getUserHandler);
app.openapi(createUserRoute, createUserHandler);
app.openapi(updateUserRoute, updateUserHandler);
// Base configuration
const baseDocConfig = {
info: {
version: '1.0.0',
title: 'User Management API',
description: 'A RESTful API for managing users',
contact: {
name: 'API Support',
email: 'support@example.com',
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT',
},
},
externalDocs: {
description: 'Find more info here',
url: 'https://docs.example.com',
},
};
// OpenAPI 3.0 endpoint
app.doc('/openapi.json', {
openapi: '3.0.0',
...baseDocConfig,
});
// OpenAPI 3.1 endpoint with enhanced features
app.doc31('/openapi31.json', {
openapi: '3.1.0',
...baseDocConfig,
});
// Development vs production servers
app.doc('/openapi.json', (c) => {
const isDevelopment = process.env.NODE_ENV === 'development';
return {
openapi: '3.0.0',
...baseDocConfig,
servers: isDevelopment
? [
{ url: 'http://localhost:3000', description: 'Development server' },
]
: [
{ url: 'https://api.example.com', description: 'Production server' },
{ url: 'https://staging-api.example.com', description: 'Staging server' },
],
};
});
// Serve static Swagger UI (example with additional middleware)
import { serveStatic } from 'hono/serve-static';
app.get('/docs', serveStatic({ path: './swagger-ui.html' }));
app.use('/docs/*', serveStatic({ root: './swagger-ui/' }));Documentation endpoints automatically handle errors during generation.
Usage Examples:
// Documentation endpoints automatically handle generation errors
app.doc('/openapi.json', {
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'My API',
},
});
// If generation fails, returns 500 with error details
// Example error response:
// {
// "message": "OpenAPI generation failed",
// "error": "Invalid schema definition in route /users"
// }
// Custom error handling (not typically needed)
app.get('/custom-openapi', (c) => {
try {
const document = app.getOpenAPIDocument({
openapi: '3.0.0',
info: { version: '1.0.0', title: 'My API' },
});
return c.json(document);
} catch (error) {
return c.json({
error: 'Failed to generate OpenAPI document',
details: error instanceof Error ? error.message : 'Unknown error',
}, 500);
}
});OpenAPI documents automatically adjust paths when using base paths.
Usage Examples:
// App with base path
const apiApp = app.basePath('/api/v1');
// Register routes on the base path app
apiApp.openapi(userRoute, userHandler); // Route: /users -> /api/v1/users
// Documentation will include the base path
apiApp.doc('/openapi.json', {
openapi: '3.0.0',
info: { version: '1.0.0', title: 'My API' },
});
// Generated document will have paths like:
// "/api/v1/users": { "get": { ... } }