or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-openapi.mdindex.mdopenapi-generation.mdroute-creation.mdvalidation-error-handling.md
tile.json

openapi-generation.mddocs/

OpenAPI Document Generation

OpenAPI document generation methods supporting both OpenAPI 3.0 and 3.1 specifications with configurable generation options and automatic endpoint creation.

Capabilities

OpenAPI 3.0 Document Generation

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));

OpenAPI 3.1 Document Generation

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',
  }
);

OpenAPI 3.0 Documentation Endpoint

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,
  })
);

OpenAPI 3.1 Documentation Endpoint

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

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';
}

Complete Documentation Setup

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/' }));

Error Handling in Documentation Endpoints

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);
  }
});

Base Path Handling

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": { ... } }