Skip to content

OpenAPI Generator Configuration: Customizing Generated Code Output

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about OpenAPI Generator Configuration: Customizing Generated Code Output. We cover key concepts, practical examples, and best practices to help you master this topic.

OpenAPI Generator configuration customizes every aspect of generated code through YAML config files, per-generator options, type mappings, import mappings, schema mappings, and post-processing hooks.

What You'll Learn

How to customize OpenAPI Generator output: create configuration YAML files, use per-generator options, configure type mappings (custom types for dates, numbers), import mappings (custom library paths), schema mappings (custom model names), and use post-processing hooks.

Why It Matters

Default output rarely matches project conventions. Configuration ensures generated code follows your naming conventions, uses your preferred libraries, and integrates with your existing codebase. DodaTech uses config to generate Spring Boot code with MapStruct instead of manual mappers.

Real-World Use

DodaTech generates Python clients. The default output uses urllib3 but their codebase uses httpx. A config option switches the HTTP library. Type mappings change date from date to datetime. Import mappings add custom base classes.

flowchart LR
    A["Default\nOutput"] --> B["Configuration\nYAML"]
    B --> C["Generator\nOptions"]
    B --> D["Type\nMappings"]
    B --> E["Import\nMappings"]
    B --> F["Post-Processing\nHooks"]
    C --> G["Customized\nOutput"]
    D --> G
    E --> G
    F --> G
    style A fill:#fef3c7,stroke:#d97706
    style G fill:#bbf7d0,stroke:#16a34a

Configuration YAML Structure

# full-config.yaml
# Complete configuration for a Python client generator

# Basic settings
inputSpec: ./openapi.yaml
generatorName: python
outputDir: ./generated/client
templateDir: ./custom-templates
library: httpx  # Override default HTTP library

# Package configuration
packageName: dodatech_api_client
projectName: dodatech-api-client
packageVersion: 2.0.0

# API and model packages
apiPackage: dodatech.api
modelPackage: dodatech.models

# Generator-specific options
configOptions:
  # Code style
  sortParamsByRequiredFlag: true
  sortModelPropertiesByRequiredFlag: true
  hideGenerationTimestamp: true
  generateSourceCodeOnly: false

  # Naming conventions
  modelPropertyNaming: camelCase
  paramNaming: camelCase
  variableNaming: snake_case

  # Serialization
  dateFormat: iso8601
  collectionFormat: multi

  # Documentation
  packageUrl: https://github.com/dodatech/api-client

# Type mappings (override default type handling)
typeMappings:
  date: datetime.date
  DateTime: datetime.datetime
  decimal: Decimal
  file: io.BytesIO

# Import mappings (customize import paths)
importMappings:
  User: dodatech.models.user.User
  Order: dodatech.models.order.Order
  ApiException: dodatech.exceptions.ApiException

# Schema mappings (rename generated models)
schemaMappings:
  CreateUserRequest: UserCreate
  UpdateUserRequest: UserUpdate
  ListUsersResponse: UserList

Generator-Specific Options

# python-specific options
configOptions:
  library: httpx                  # Default: urllib3
  packageName: dodatech_client    # Default: openapi_client
  useNose: false                  # Use pytest instead of nose
  generateSourceCodeOnly: true    # Don't generate docs/tests

# java/spring-specific options
configOptions:
  useSpringBoot3: true            # Spring Boot 3 vs 2
  useJakartaEe: true              # Jakarta vs javax
  dateLibrary: java8              # java8, threetenbp, joda
  serializationLibrary: jackson   # jackson, gson
  openApiNullable: true           # OpenAPI 3.0 nullable support
  useSeperateModelProject: true   # Separate module for models
  hideGenerationTimestamp: true   # Don't add timestamp comments
  interfaceOnly: true             # Generate only interfaces
  skipDefaultInterface: false     # Generate default methods

# javascript-specific options
configOptions:
  usePromises: true               # Use Promise instead of callbacks
  useES6: true                    # ES6 module syntax
  moduleName: DodatechApi         # Module export name
  projectName: dodatech-api       # npm package name

Type and Import Mappings

# Custom type mappings
typeMappings:
  # Spec type -> Language-specific type
  integer: int                      # Python mapping
  long: int                         # Python: no long type
  number: Decimal                   # Use Decimal for precision
  date: datetime.date               # Python date
  date-time: datetime.datetime      # Python datetime
  binary: io.BytesIO                # Binary data
  file: io.BytesIO                  # File uploads

# Import mappings (custom imports)
importMappings:
  # When generator references these types, use custom imports
  User: com.dodatech.model.User
  Order: com.dodatech.model.Order
  PaginatedResponse: com.dodatech.model.PaginatedResponse
  ApiError: com.dodatech.exception.ApiError
  OffsetDateTime: java.time.OffsetDateTime

# Schema mappings (rename generated model classes)
schemaMappings:
  # Spec schema name -> Generated class name
  CreateUserRequest: UserCreateRequest
  UpdateUserRequest: UserUpdateRequest
  LoginRequest: LoginCredentials
  ApiResponse: ApiResultWrapper
  PaginatedUsers: UserPage

Post-Processing with Hooks

# custom-scripts/post-generate.py
# Run after `openapi-generator generate` to customize output
import os
import shutil
import re

def post_process_generated(output_dir):
    """Post-process generated files."""
    for root, dirs, files in os.walk(output_dir):
        for file in files:
            filepath = os.path.join(root, file)

            if file.endswith('.py'):
                modify_python_file(filepath)
            elif file.endswith('.java'):
                modify_java_file(filepath)

def modify_python_file(filepath):
    """Add custom annotations to generated Python code."""
    with open(filepath, 'r') as f:
        content = f.read()

    # Add custom base class to all models
    content = content.replace(
        'class BaseModel:',
        'class BaseModel(DodaTechBaseModel):'
    )

    # Add logging decorator to all API methods
    content = re.sub(
        r'def (get_|create_|update_|delete_)',
        r'@log_api_call\n    def \1',
        content
    )

    with open(filepath, 'w') as f:
        f.write(content)

# Usage:
# python custom-scripts/post-generate.py

Common Mistakes

1. Not Validating Config Before Generation

A typo in config YAML causes generation to use defaults silently. Validate config structure: check option names against the generator's documentation. Run generation with --dry-run to preview.

2. Overriding Too Many Defaults

Customizing every aspect makes upgrading the generator harder. Only override what differs from project conventions. Let defaults handle standard cases.

3. Confusing Type Mappings with Schema Mappings

Type mappings change data types (string -> UUID). Schema mappings change model class names (CreateUserRequest -> UserCreationPayload). They serve different purposes and are configured differently.

4. Not Using Generator-Specific Options

Each generator has unique options that significantly affect output. Python's library option switches between urllib3, requests, and httpx. Java's interfaceOnly generates only interfaces. Read each generator's docs.

5. Ignoring Post-Processing for Complex Customizations

Some customizations aren't possible via config YAML. Use post-processing scripts to modify generated files, add annotations, insert base classes, or format code according to project standards.

Practice Questions

  1. What is the difference between typeMappings and importMappings?
  2. How do you change the HTTP library for Python generation?
  3. What are schema mappings used for?
  4. When should you use post-processing scripts?

Answers:

  1. typeMappings change the target language data type ($ref -> custom class). importMappings change the import path when the generator references a type. Both affect how types are imported and used.
  2. Set library: httpx in configOptions for the python generator. Default is urllib3. Other options: requests, asyncio. This changes the underlying HTTP client library.
  3. Schema mappings rename generated model classes. Use when spec schema names don't match your naming conventions. Example: CreateUserRequest mapping to UserCreationPayload for the generated class name.
  4. Use post-processing when config options can't achieve the desired output: adding custom annotations, inserting base class inheritance, applying custom formatting, or removing boilerplate.

Challenge: Create a comprehensive config YAML for a Python client generator: customize package name, HTTP library (httpx), type mappings (date -> datetime, decimal -> Decimal), import mappings for 3 custom types, schema mappings for 4 model renames, and a post-processing script that adds a @log_api_call decorator to all API methods.

FAQ

{{< faq "How do I find available config options for a generator?" >}} {{< faq "What is the difference between additionalProperties and configOptions?" >}} {{< faq "Can I use environment variables in config YAML?" >}} {{< faq "How do I configure generation for multiple languages from one config?" >}} {{< faq "What happens if I set an invalid config option?" >}}

Mini Project

Create a comprehensive OpenAPI Generator config for a Spring Boot server: configure Jakarta EE, Java 17 date types, custom API/model packages, type mappings for all date types, import mappings for 5 custom types, schema mappings for 5 model classes, and a post-processing script that adds Swagger @Schema annotations.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro