# How OpenAPI Documentation is Auto-Generated from Decorators in the TCC Repository

> Learn how the TCC repository auto-generates OpenAPI documentation from decorators using the chanfana library. Eliminate manual spec files and streamline your API development.

- Repository: [Lucas Zanoni⠀⠀⠀⠀⠀ ⠀╱|、 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ (˚ˎ 。7 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |、˜〵 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ じしˍ,)ノ/tcc](https://github.com/castrozan/tcc)
- Tags: how-to-guide
- Published: 2026-02-27

---

**The TCC repository uses the chanfana library to automatically generate OpenAPI documentation by extending the `OpenAPIRoute` base class in controllers and registering them with `fromHono`, eliminating the need for manual YAML or JSON specification files.**

The `castrozan/tcc` repository demonstrates a modern approach to API development where documentation stays synchronized with implementation code. By leveraging **chanfana**—a thin wrapper around the **Hono** web framework—the project auto-generates complete Swagger UI documentation directly from TypeScript decorators and static schema definitions.

## The Architecture Behind Auto-Generated OpenAPI Documentation

### The chanfana Library and OpenAPIRoute Base Class

At the heart of the system is the `OpenAPIRoute` class provided by chanfana. Controllers in the TCC repository extend this base class to gain OpenAPI generation capabilities. Each controller defines a static `schema` property that follows the OpenAPI v3 specification structure, including tags, request bodies, responses, and security requirements.

When a controller extends `OpenAPIRoute`, chanfana can introspect the class at runtime to extract the declarative schema and map it to the corresponding HTTP endpoint.

### The fromHono Factory Function

The `fromHono` function initializes the integration between Hono and chanfana. It accepts a Hono application instance and configuration options, returning an enhanced object that manages both route registration and OpenAPI documentation assembly.

This factory creates an internal registry that accumulates path definitions, security schemes, and component schemas as controllers are registered.

## Step-by-Step Implementation Flow

### 1. Define Controllers Extending OpenAPIRoute

Each API endpoint is implemented as a class that extends `OpenAPIRoute` and provides a static `schema` object. For example, in [`src/presentation/controllers/professionals/CreateProfessionalController.ts`](https://github.com/castrozan/tcc/blob/main/src/presentation/controllers/professionals/CreateProfessionalController.ts):

```typescript
import { Bool, OpenAPIRoute } from 'chanfana';
import { CreateProfessionalUseCase } from 'application/use-cases/professionals/CreateProfessionalUseCase';
import { withErrorHandling } from 'presentation/decorators';
import { z } from 'zod';

export class CreateProfessionalController extends OpenAPIRoute {
  schema = {
    tags: ['Professionals'],
    summary: 'Create a new professional',
    security: [{ bearerAuth: [] }],
    request: {
      body: {
        content: {
          'application/json': {
            schema: z.object({
              name: z.string().min(1),
              role: z.string().min(1),
            })
          }
        }
      }
    },
    responses: {
      '201': {
        description: 'Created',
        content: {
          'application/json': {
            schema: z.object({
              success: Bool(),
              result: z.object({ id: z.number() })
            })
          }
        }
      }
    }
  };

  @withErrorHandling
  async handle() {
    // Implementation logic
  }
}

```

The `schema` property uses Zod for runtime validation and OpenAPI schema generation, while `OpenAPIRoute` enables chanfana to discover this metadata.

### 2. Register Routes with fromHono

In [`src/infrastructure/web/open-api/server.ts`](https://github.com/castrozan/tcc/blob/main/src/infrastructure/web/open-api/server.ts), the server bootstrap registers controllers using methods on the object returned by `fromHono`:

```typescript
import { fromHono } from 'chanfana';
import { Hono } from 'hono';
import { config } from 'dotenv';
import {
  CreateProfessionalController,
  DeleteProfessionalController,
  FindAllProfessionalController,
  FindByIdProfessionalController,
  UpdateProfessionalController
} from 'presentation/controllers/professionals';

const app = new Hono();

const openapi = fromHono(app, {
  docs_url: '/',
  schema: {
    security: [{ bearerAuth: [] }]
  }
});

openapi.registry.registerComponent('securitySchemes', 'bearerAuth', {
  type: 'http',
  scheme: 'bearer'
});

config();

openapi.get('/public/professional', FindAllProfessionalController);
openapi.get('/public/professional/:id', FindByIdProfessionalController);
openapi.put('/professional', UpdateProfessionalController);
openapi.post('/professional', CreateProfessionalController);
openapi.delete('/professional/:id', DeleteProfessionalController);

export default app;

```

Each `openapi.<method>()` call extracts the static `schema` from the controller and adds it to the internal OpenAPI registry.

### 3. Configure Security Components

The server registers a reusable `bearerAuth` security scheme using `openapi.registry.registerComponent`. This scheme is referenced in each controller's `security` array, ensuring consistent authentication documentation across all endpoints.

### 4. Serve Documentation via docs_url

The `docs_url: '/'` configuration option instructs `fromHono` to expose Swagger UI at the root path. When the server starts, chanfana assembles the complete OpenAPI specification from the registry and serves it at this endpoint.

## How the OpenAPI JSON Specification is Produced

During server initialization, `fromHono` constructs an internal `OpenAPIV3.Document` object. For each registered route, the library:

1. Reads the HTTP method from the registration call (`get`, `post`, `put`, `delete`).
2. Introspects the controller class to extract the static `schema` property.
3. Maps the schema to the corresponding `paths[<path>][<method>]` entry in the OpenAPI document.
4. Merges globally registered components, such as the `bearerAuth` security scheme.

When a client requests the `docs_url` endpoint, chanfana returns the fully populated specification, which Swagger UI renders into interactive documentation.

## Summary

- The **chanfana** library enables **OpenAPI documentation auto-generated from decorators** by providing the `OpenAPIRoute` base class.
- Controllers define declarative `schema` objects that follow OpenAPI v3 structure, using Zod for type safety and validation.
- The `fromHono` factory function registers routes and automatically assembles the OpenAPI specification into an internal registry.
- Security components like `bearerAuth` are registered once and referenced across all controllers for consistent authentication documentation.
- The `docs_url` configuration serves Swagger UI automatically, ensuring documentation stays synchronized with code changes without manual maintenance.

## Frequently Asked Questions

### What library does the TCC repository use for OpenAPI auto-generation?

The repository uses **chanfana**, a thin wrapper around the Hono web framework. Chanfana provides the `OpenAPIRoute` base class and `fromHono` factory function that enable automatic OpenAPI specification generation from TypeScript controller classes and their static schema definitions.

### How does the schema property in controllers relate to OpenAPI specification?

The `schema` property is a static object defined on each controller class that extends `OpenAPIRoute`. It follows the OpenAPI v3 specification structure, including properties like `tags`, `summary`, `request`, `responses`, and `security`. Chanfana reads this static property during route registration and maps it directly to the corresponding path and method in the generated OpenAPI document.

### Is manual YAML or JSON required to maintain API documentation in this setup?

No manual YAML or JSON files are required. The documentation is generated entirely from the TypeScript source code. Developers only need to maintain the `schema` property within their controller classes. When the server starts, `fromHono` assembles the complete OpenAPI specification from these schemas, and the `docs_url` endpoint serves the Swagger UI automatically.

### What role does the fromHono function play in documentation generation?

The `fromHono` function initializes the integration between the Hono application and chanfana's OpenAPI registry. It returns an enhanced object that provides methods like `get`, `post`, `put`, and `delete` for registering routes. When these methods are called with a controller class, `fromHono` introspects the class to extract its `schema`, registers the route with Hono, and adds the corresponding OpenAPI path entry to an internal registry that ultimately produces the complete specification document.