Generated Code
Understanding the structure and usage of generated API clients.
Overview
The OpenAPI Generator creates three TypeScript files that work together to provide a complete, type-safe API client.
File Structure
A. models.ts
Contains all Zod schemas derived from your OpenAPI components:
- Schemas - Converted from
components.schemasdefinitions - Type exports - TypeScript types inferred from Zod schemas
- Validation - Runtime validation using Zod
Example generated model:
import { z } from 'zod'
export const User = z.object({
id: z.string(),
username: z.string(),
email: z.email(),
createdAt: z.iso.datetime()
})
export type UserModel = z.infer<typeof User>B. api.ts
Contains the hierarchical router mapping all API endpoints:
- Base URL - Extracted from
servers[0].urlin the specification - Nested routes - Path segments become nested objects
- HTTP methods - Each method is a pre-configured builder
- Type inference - Full TypeScript support for all operations
Example generated API:
import { f } from '@freestylejs/fetch'
import { z } from 'zod'
import * as Model from './models'
export const api = f.router('https://api.example.com', {
users: {
$userId: {
GET: f.builder()
.def_json()
.def_response(async ({ json }) => Model.User.parse(await json())),
posts: {
GET: f.builder()
.def_json()
.def_searchparams(z.object({
page: z.number().optional(),
limit: z.number().optional()
}).parse)
.def_response(async ({ json }) => z.array(Model.Post).parse(await json()))
}
}
}
})C. auth.ts
Contains type-safe authentication configuration and middleware factory:
- AuthConfig - Interface matching your OpenAPI security schemes
- Middleware Factory - Creates authentication middleware based on config
- Supported Schemes - Bearer, Basic, API Key, OAuth2
Example generated auth:
import { f, type Middleware } from '@freestylejs/fetch'
export interface AuthConfig {
/** Bearer authentication */
bearerAuth?: {
token: string | (() => Promise<string>)
}
/** API Key authentication */
apiKey?: {
value: string | (() => Promise<string>)
}
}
export const createAuthMiddleware = (config: AuthConfig) => {
const middlewares: Middleware[] = []
// ... middleware implementation
return middlewares
}D. index.ts
Re-exports all generated code:
export * from './api'
export * from './models'
export * from './auth'Usage Patterns
A. Client Initialization & Authentication
The generated code exports a createClient factory function that allows you to configure the base URL and authentication credentials.
import { createClient } from './api'
// Initialize with auth configuration
const client = createClient({
baseUrl: 'https://api.example.com', // Optional override
auth: {
// Type-safe config based on your OpenAPI security schemes
bearerAuth: {
token: 'my-secret-token'
},
apiKey: {
// Supports async functions for token rotation
value: async () => await getApiKey()
}
}
})
// Use the authenticated client
const user = await client.users.me.GET()B. Path Parameters
Dynamic path segments use the $paramName syntax:
// OpenAPI: /users/{userId}
// Generated: client.users.$userId
const user = await client.users.$userId.GET({
params: { userId: '123' }
})C. Query Parameters
Query parameters are validated with Zod schemas:
// OpenAPI: /users?page=1&limit=10
// Generated with searchparams
const users = await client.users.GET({
query: {
page: 1,
limit: 10
}
})D. Request Bodies
Request bodies are validated against Zod schemas:
// OpenAPI: POST /users with body
// Generated with def_body
const newUser = await client.users.POST({
body: {
username: 'john',
email: 'john@example.com'
}
})E. Response Validation
Responses are automatically validated:
// Response is validated with zod at runtime
const user = await client.users.$userId.GET({
params: { userId: '123' }
})
// TypeScript knows the exact shape
user.username // string
user.email // stringType Inference
The generated client provides complete type inference:
A. Request Types
// TypeScript infers the shape of params, query, and body
client.users.$userId.GET({
params: { userId: '123' }, // Type: { userId: string }
query: { include: 'posts' } // Type: { include?: string }
})B. Response Types
// Response type is inferred from the Zod schema
const user = await client.users.$userId.GET({
params: { userId: '123' }
})
// user: UserModelSchema Conversion
The generator converts OpenAPI types to Zod schemas:
| OpenAPI Type | Zod Schema | Example |
|---|---|---|
string | z.string() | "hello" |
number | z.number() | 42 |
integer | z.number().int() | 10 |
boolean | z.boolean() | true |
array | z.array(...) | [1, 2, 3] |
object | z.object({...}) | { key: "value" } |
string (format: date-time) | z.iso.datetime() | "2024-01-01T00:00:00Z" |
string (format: email) | z.email() | "user@example.com" |
string (format: uuid) | z.uuid() | "123e4567-e89b-12d3-..." |
string (format: uri) | z.url() | "https://example.com" |
string (enum) | z.enum([...]) | "active" |
allOf | Schema1.and(Schema2) | Intersection |
oneOf | z.union([...]) | Union |
oneOf (discriminator) | z.discriminatedUnion(...) | Discriminated union |
Naming Conventions
The generator converts OpenAPI names to PascalCase:
user-profile→UserProfileapi_key→ApiKeyuserSettings→UserSettings
Special characters like $ are preserved:
$special→$Special
Related
- Authentication - Configure auth credentials
- Validation - Runtime validation details
- CLI Reference - Generation options
- Fetch Builder - Understanding the builder API