Custom OpenAPI Generator Templates — Build Your Own Code Generation
In this tutorial, you will learn about Custom OpenAPI Generator Templates. We cover key concepts, practical examples, and best practices to help you master this topic.
Custom OpenAPI Generator templates let you override default Code Generation and produce output tailored to your project's architecture, naming conventions, and framework choices.
What You'll Learn
How to create custom OpenAPI Generator templates using Mustache syntax, override default template files, configure custom template directories, and build a production-ready custom template set for your API ecosystem.
Why It Matters
Default templates produce generic code. Custom templates enforce your team's conventions, include your logging middleware, add authentication boilerplate, generate integration tests automatically, and ensure every service follows the same patterns. DodaTech uses custom templates to embed OpenTelemetry tracing in every generated server stub.
Real-World Use
DodaTech's platform team maintains a custom template set that adds structured logging, request ID middleware, health check endpoints, and Prometheus metrics to every generated Python FastAPI server. A new microservice is ready for production deployment within 5 minutes of spec generation.
flowchart LR
A["OpenAPI\nSpec"] --> B["openapi-generator"]
B --> C["Custom\nTemplates"]
B --> D["Default\nTemplates"]
C --> E["Team-consistent\nCode Output"]
subgraph "Template Directory"
F["controller.mustache"]
G["model.mustache"]
H["api.mustache"]
I["main.mustache"]
end
style C fill:#fef3c7,stroke:#d97706
style E fill:#bbf7d0,stroke:#16a34a
Understanding Template Files
OpenAPI Generator uses Mustache templates for every generated file. Each generator has a set of template files organized by role:
| Template File | Purpose | Generated Output |
|---|---|---|
controller.mustache |
API endpoint handlers | Route implementations |
model.mustache |
Data model classes | Request/response DTOs |
api.mustache |
API client class | HTTP client library |
api_doc.mustache |
API documentation | Markdown/HTML docs |
main.mustache |
Application entry point | Main server module |
openapi.mustache |
API spec | OpenAPI specification |
Building a Custom Template Set
# Custom template directory structure:
# templates/
# python-fastapi/
# controller.mustache
# model.mustache
# api.mustache
# main.mustache
template_dir = "templates/python-fastapi/"
generator = "python-fastapi"
spec = "openapi.yaml"
output = "gen/"
# Generate with custom templates:
cmd = (
f"openapi-generator generate "
f"-i {spec} "
f"-g {generator} "
f"-o {output} "
f"-t {template_dir}"
)
print(f"Command: {cmd}")
print("Expected output:")
print(" Generated controller stubs with custom error handling")
print(" Generated models with custom serialization")
print(" Generated API client with custom retry logic")
Custom Controller Template Example
# controllers/{{classname}}Controller.py
from typing import List, Optional
from fastapi import APIRouter, HTTPException, Request
from {{packageName}}.middleware import log_request, trace_request
from {{packageName}}.models.{{importPath}} import {{classname}}Model
router = APIRouter(prefix="/{{basePath}}")
@router.{{httpMethod}}("{{path}}")
@log_request
@trace_request
async def {{operationId}}(
request: Request,
{{#queryParams}}
{{paramName}}: {{dataType}} = None,
{{/queryParams}}
{{#bodyParams}}
body: {{dataType}},
{{/bodyParams}}
):
"""
{{summary}}
"""
try:
# Custom middleware is injected automatically
result = await {{operationId}}_handler({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}})
return {"data": result, "status": "ok"}
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail="Internal error")
Expected behavior: This template wraps every endpoint with @log_request and @trace_request decorators, adds structured error handling, and returns a consistent JSON envelope.
Using Custom Templates with Config File
# openapi-generator-config.yaml
generatorName: python-fastapi
inputSpec: openapi.yaml
outputDir: gen/
templateDir: templates/python-fastapi/
additionalProperties:
packageName: orders_service
usePrometheus: true
logLevel: INFO
globalProperties:
skipFormModel: false
apiDocs: false
modelDocs: false
# Generate with config file:
openapi-generator generate -c openapi-generator-config.yaml
echo "Generation complete"
# Expected output:
# Generating with custom templates from: templates/python-fastapi/
# Output: gen/
# Files generated: 24
Common Mistakes
1. Not Matching Template Variable Names
OpenAPI Generator uses specific variable names that vary by generator. Always check the generator's default templates before creating custom versions. Missing variables cause silent rendering failures.
2. Overriding Too Many Templates
Start by overriding only the templates you need (usually controller.mustache and model.mustache). Overriding all templates creates maintenance burden when the generator updates its internal models.
3. Ignoring Partial Templates
Templates can reference partials like {{>partials/header}}. If you override a template that uses partials, you must also override those partials or ensure the defaults are compatible.
4. Breaking Template Syntax
Mustache is logic-less but has strict syntax. A missing closing {{/block}} or mismatched section name causes the entire template to render as empty string. Validate templates by generating with a minimal spec first.
5. Not Testing Generated Output
Always compile and test generated code after template changes. A template change that produces invalid syntax breaks every service generation. Add a CI step that generates code from a test spec and verifies it compiles.
Practice Questions
- What is the purpose of custom OpenAPI Generator templates?
- How do you specify a custom template directory?
- What Mustache syntax is used for conditionals?
- Why should you template partials?
Answers:
- Custom templates override default code generation to enforce team conventions, add custom middleware, and produce consistent output across all generated services.
- Use the
-tflag with the CLI ortemplateDirin the config file pointing to the directory containing the custom Mustache template files. {{#condition}}...{{/condition}}renders the block if truthy,{{^condition}}...{{/condition}}renders if falsey.- Partials are reusable template fragments. If you override a template that includes a partial, the default partial may not match the new template structure, so you must also override the referenced partials.
Challenge: Create a custom template set for the Python Flask generator that adds request logging, CORS headers, health check endpoint, and structured error responses. Test it by generating code from a pet store spec and verifying the output compiles.
FAQ
Mini Project
Extract default templates for the Python Flask generator, customize the controller template to add request validation, CORS middleware, and structured JSON error responses, then generate code from a real API spec and verify the server runs correctly.
What's Next
Generator Options — advanced options for customizing code generation.
Mustache Templates Deep Dive — learn advanced Mustache template patterns.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro