OpenAPI Generator — Auto-Generate Client SDKs Guide
In this tutorial, you'll learn about OpenAPI Generator. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
OpenAPI Generator auto-generates client SDKs, server stubs, and API documentation from an OpenAPI specification, eliminating manual API client code and keeping SDKs in sync with the spec.
What You'll Learn
You will learn to use OpenAPI Generator to produce type-safe clients in multiple languages, customize the output, integrate generation into CI/CD, and maintain SDK quality.
Why Code Generation Matters
Writing API clients by hand is repetitive, error-prone, and hard to keep in sync. Every endpoint change requires updating every client library. DodaTech publishes SDKs for 5 languages — OpenAPI Generator keeps them consistent and reduces release time from days to minutes.
Installing OpenAPI Generator
# Using npm (Node.js)
npm install @openapitools/openapi-generator-cli -g
# Using Homebrew
brew install openapi-generator
# Using Docker
docker pull openapitools/openapi-generator-cli
# Verify
openapi-generator version
openapi-generator-cli version
Expected output:
openapi-generator version 7.8.0
Generating a TypeScript Client
openapi-generator generate \
-i https://api.durga.dodatech.com/v2/openapi.json \
-g typescript-fetch \
-o ./sdks/typescript \
--additional-properties=supportsES6=true,npmName=@dodatech/threat-api
cd ./sdks/typescript
npm install
npm run build
Expected output:
[main] INFO o.o.codegen.DefaultGenerator - Generated 'ThreatApi' (api)
[main] INFO o.o.codegen.DefaultGenerator - Generated 'Threat' (model)
[main] INFO o.o.codegen.Generator - Done. SDK generated to ./sdks/<a href="/programming-languages/typescript/">TypeScript</a>
Generated TypeScript client usage:
import { ThreatApi, Configuration } from "@dodatech/threat-api";
const config = new Configuration({
basePath: "https://api.durga.dodatech.com/v2",
apiKey: "dodatech_partner_key_abc123",
});
const api = new ThreatApi(config);
async function main() {
// All methods are typed from the spec
const threats = await api.listThreats({ severity: "critical" });
console.log(threats.data); // Typed as Threat[]
const result = await api.getThreat({ threatId: "thr_042" });
console.log(result.name); // Autocompleted in IDE
}
Expected output:
[
{ id: "thr_001", name: "Emotet", severity: "critical", detected_at: "..." },
{ id: "thr_002", name: "Mirai", severity: "critical", detected_at: "..." }
]
Generating a Python Client
openapi-generator generate \
-i spec/openapi.yaml \
-g python \
-o ./sdks/python \
--additional-properties=packageName=dodatech_threat_api
cd ./sdks/python
pip install -e .
Expected output:
[main] INFO o.o.codegen.DefaultGenerator - Generating Python client...
[main] INFO o.o.codegen.Generator - Done.
# Installed editable package: dodatech-threat-api
Generated Python client usage:
from dodatech_threat_api import ThreatApi, ApiClient, Configuration
config = Configuration(
host="https://api.durga.dodatech.com/v2",
api_key={"X-API-Key": "dodatech_partner_key_abc123"},
)
with ApiClient(config) as client:
api = ThreatApi(client)
threats = api.list_threats(severity="critical")
for threat in threats.data:
print(f"{threat.name} ({threat.severity})")
Expected output:
Emotet (critical)
Mirai (critical)
AgentTesla (medium)
Customizing Generated Code
Use a .openapi-generator-ignore file to exclude or override specific files.
# .openapi-generator-ignore
**/api_client.py # Use custom base client
**/models/*_internal.py # Skip private models
docs/ # Skip auto-generated docs
# openapi-generator-config.yaml
additionalProperties:
supportsES6: true
npmName: "@dodatech/threat-api"
withInterfaces: true
typescriptThreePlus: true
enumNameSuffix: ""
generateBuilders: false
useSingleRequestParameter: true
CI/CD Integration
# .github/workflows/sdk-publish.yml
name: Generate and Publish SDKs
on:
push:
paths:
- "spec/openapi.yaml"
jobs:
generate:
runs-on: ubuntu-latest
strategy:
matrix:
lang: [typescript-fetch, python, go, java]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
if: matrix.lang == 'typescript-fetch'
with: { node-version: "20" }
- uses: actions/setup-python@v5
if: matrix.lang == 'python'
with: { python-version: "3.12" }
- uses: actions/setup-go@v5
if: matrix.lang == 'go'
with: { go-version: "1.22" }
- name: Generate SDK
run: |
openapi-generator generate \
-i spec/openapi.yaml \
-g ${{ matrix.lang }} \
-o sdks/${{ matrix.lang }}
- name: Publish to registry
run: |
# Publish to npm, PyPI, Go module registry, etc.
cd sdks/${{ matrix.lang }}
make publish
Expected CI output:
✅ OpenAPI Generator: typescript-fetch → sdks/typescript
✅ OpenAPI Generator: python → sdks/python
✅ OpenAPI Generator: go → sdks/go
✅ OpenAPI Generator: java → sdks/java
📦 Published @dodatech/threat-api@2.1.0 to npm
📦 Published dodatech-threat-api==2.1.0 to PyPI
flowchart LR
A["OpenAPI Spec\nopenapi.yaml"] --> B["OpenAPI Generator"]
B --> C["TypeScript SDK"]
B --> D["Python SDK"]
B --> E["Go SDK"]
B --> F["Java SDK"]
B --> G["Server Stub\n(Optional)"]
C --> H["npm publish"]
D --> I["PyPI publish"]
E --> J["Go module"]
F --> K["Maven Central"]
H --> L["Partners use\nnpm install"]
I --> L
style A fill:#dbeafe,stroke:#2563eb
style B fill:#bbf7d0,stroke:#16a34a
style L fill:#fef3c7,stroke:#d97706
Generated Server Stubs
# Generate a Python Flask server stub
openapi-generator generate \
-i spec/openapi.YAML \
-g Python-Flask \
-o ./server-stub
cd ./server-stub
Pip install -R requirements.txt
Python -m openapi_server
Expected output:
* Running on HTTP://0.0.0.0:8080
* Swagger UI at HTTP://localhost:8080/v2/ui/
* OpenAPI spec at HTTP://localhost:8080/v2/openapi.JSON
Common Errors
1. Spec Validation Failures
OpenAPI Generator requires a valid spec. Run openapi-generator validate -i spec.yaml before generation. Invalid specs produce cryptic errors.
2. Generated Code Does Not Compile
Some generators produce code that requires specific library versions. Always check the requirements.txt or package.json in the generated output and install dependencies.
3. Ignoring apiVersion Override Persistence
Generator settings are saved to .openapi-generator/VERSION and reused. Delete this file when upgrading the generator to avoid stale defaults.
4. Missing Discriminator for Polymorphism
Polymorphic types require discriminator in the spec. Without it, generated deserialization code may produce incorrect types.
5. Not Testing Generated Clients
Generated code can have edge-case bugs. Write integration tests that call the actual API through the generated client.
Practice Questions
1. What is the main benefit of OpenAPI Generator?
It eliminates manual SDK code. Spec changes are automatically reflected in all generated clients, ensuring consistency across languages.
2. How do you customize generated code without modifying templates?
Use .openapi-generator-ignore to exclude files and additionalProperties in the configuration to control output options.
3. What does the -g flag specify?
The generator name (target language or framework), such as <a href="/programming-languages/typescript/">TypeScript</a>-fetch, python, go, java, or python-flask for server stubs.
4. Challenge: Generate a Go client from the Durga threat API spec and write a 5-line program that fetches critical threats.
package main
import (
dodatech "github.com/dodatech/threat-API-Go"
)
func main() {
client := dodatech.NewAPIClient(dodatech.NewConfiguration())
threats, _, _ := client.ThreatApi.ListThreats(context.Background(), nil)
threats.Data[0].GetName() // "Emotet"
}
Mini Project: SDK Generation Pipeline
Create an OpenAPI spec for a simplified Durga Antivirus Pro threat API with list, get, and search endpoints. Generate TypeScript and Python SDKs, publish them to local registries, and write a sample integration for each language.
Related Tutorials
RESTful API Design — OpenAPI Specification — CI/CD Setup
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-24.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro