OpenAPI Generator Client SDKs: Generate API Clients for Any Platform
In this tutorial, you will learn about OpenAPI Generator Client SDKs: Generate API Clients for Any Platform. We cover key concepts, practical examples, and best practices to help you master this topic.
Client SDK generation creates language-specific API client libraries from OpenAPI specs, providing typed interfaces, automatic Serialization, authentication handling, and retry logic for consuming APIs.
What You'll Learn
How to generate client SDKs for JavaScript, Python, Swift, Kotlin, Java, C#, and Ruby; configure client options (package name, authentication, HTTP client); add retry and error handling; and publish generated SDKs to package registries.
Why It Matters
Writing API clients manually for each platform is tedious and error-prone. Generated clients are type-safe, spec-compliant, and consistent across platforms. DodaTech generates 15 client SDKs from a single spec, published to npm, PyPI, and Maven Central.
Real-World Use
DodaTech updates the API spec. CI generates new JavaScript (npm), Python (PyPI), and Kotlin (Maven) SDKs, runs integration tests against staging, and publishes. Mobile apps update their SDK dependency and get the new API client immediately.
flowchart LR
A["OpenAPI\nSpec"] --> B["Client\nGenerator"]
B --> C["JavaScript\nfetch/axios"]
B --> D["Python\nrequests/httpx"]
B --> E["Swift\nURLSession"]
B --> F["Kotlin\nOkHttp"]
C --> G["Publish to\nnpm"]
D --> H["Publish to\nPyPI"]
E --> I["Publish to\nSPM/CocoaPods"]
F --> J["Publish to\nMaven"]
style A fill:#6cb4ee,color:#fff
style B fill:#bbf7d0,stroke:#16a34a
Generating JavaScript Client
# Generate JavaScript client (fetch API)
openapi-generator generate \
-i openapi.yaml \
-g javascript \
-o ./client-js \
--additional-properties=\
projectName=dodatech-api,\
moduleName=DodatechApi,\
usePromises=true
# Generate TypeScript client (axios)
openapi-generator generate \
-i openapi.yaml \
-g typescript-axios \
-o ./client-ts \
--additional-properties=\
npmName=@dodatech/api-client,\
npmVersion=1.0.0,\
withInterfaces=true
// Generated JavaScript client usage
const DodatechApi = require('dodatech-api');
const client = new DodatechApi.DefaultApi();
// Type-safe API calls
async function getUsers() {
try {
const users = await client.listUsers(20, 0);
console.log(`Found ${users.length} users`);
users.forEach(u => console.log(` ${u.email}`));
} catch (error) {
console.error('API Error:', error.status, error.statusText);
}
}
// Create a user with typed request body
async function createUser(email, name) {
const user = new DodatechApi.User();
user.email = email;
user.name = name;
user.password = 'SecurePass123!';
const created = await client.createUser(user);
console.log(`Created user: ${created.id} (${created.email})`);
return created;
}
Generating Python Client
# Generate Python client
openapi-generator generate \
-i openapi.yaml \
-g python \
-o ./client-python \
--additional-properties=\
packageName=dodatech_client,\
projectName=dodatech-api-client,\
packageVersion=1.0.0
# Generated Python client usage
import dodatech_client
from dodatech_client.rest import ApiException
# Configure API client
configuration = dodatech_client.Configuration(
host="https://api.dodatech.com/v1",
api_key={"ApiKeyAuth": os.environ["API_KEY"]}
)
with dodatech_client.ApiClient(configuration) as api_client:
api = dodatech_client.UsersApi(api_client)
# List users
users = api.list_users(limit=20, offset=0)
for user in users:
print(f"{user.id}: {user.email}")
# Create user
new_user = dodatech_client.User(
email="sdk-test@example.com",
name="SDK Test User",
password="SecurePassword123!"
)
try:
created = api.create_user(new_user)
print(f"Created user: {created.id}")
except ApiException as e:
print(f"API error: {e.status} - {e.body}")
Generating Swift Client
# Generate Swift iOS client
openapi-generator generate \
-i openapi.yaml \
-g swift5 \
-o ./client-swift \
--additional-properties=\
projectName=DodatechSDK,\
podName=DodatechSDK,\
usePromiseKit=true
// Generated Swift client usage
import DodatechSDK
let api = UsersAPI()
let authToken = "Bearer jwt_token_here"
api.requestBuilderFactory = URLSessionRequestBuilderFactory()
// List users
api.listUsers(limit: 20, offset: 0) { (users, error) in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
users?.forEach { user in
print("\(user.id): \(user.email ?? "")")
}
}
// Create user (PromiseKit)
let newUser = User(
email: "ios-test@example.com",
name: "iOS Test",
password: "SecurePass123!"
)
api.createUser(body: newUser)
.done { created in
print("Created user: \(created.id)")
}
.catch { error in
print("Failed: \(error)")
}
Client Configuration Options
# client-config.yaml
# Shared configuration for client generation
generatorName: python
inputSpec: ./openapi.yaml
outputDir: ./generated/client
configOptions:
# Package configuration
packageName: dodatech_client
projectName: dodatech-api-client
packageVersion: 1.0.0
# HTTP client options
library: urllib3 # or asyncio, requests
useFuture: false
# Auth and security
apiKeyPrefix: Bearer
# Code style
generateSourceCodeOnly: false
hideGenerationTimestamp: true
# Serialization
dateFormat: iso8601
collectionFormat: multi
# Generate for multiple languages from one config
# Run with: openapi-generator generate -c client-config.yaml
Common Mistakes
1. Not Setting Package Name Correctly
Default package names are generic. Set packageName, projectName, and npmName to match your naming conventions. Published packages with wrong names confuse consumers.
2. Ignoring Authentication Configuration
Generated clients don't automatically add auth headers unless configured. Set apiKeyPrefix, accessToken, or configure auth in client initialization code.
3. Not Updating Generated Clients When API Changes
API evolves, generated clients become outdated. Set up CI to regenerate and publish clients when the spec changes. Use version matching between API and client versions.
4. Publishing Generated Code Without Testing
Generated code may not compile (missing dependencies, incompatible types). Always run the generated project's test suite before publishing. Test against the real API.
5. Including Generated Build Artifacts in Source Control
Generated client code should be in CI artifacts, not in source control. Add generated directories to .gitignore. Consumers install from npm/PyPI/Maven, not from git.
Practice Questions
- What client languages does OpenAPI Generator support?
- How do you configure authentication for generated clients?
- How do you publish generated clients to package registries?
- Why should generated code be excluded from source control?
Answers:
- 50+ languages: JavaScript, TypeScript, Python (urllib3, asyncio, requests), Swift, Kotlin, Java (OkHttp, REST Assured), C# (RestSharp, HttpClient), Ruby, Dart, Go, Rust, PHP, C++, and more.
- Set
apiKeyPrefix: Bearerfor API keys, configureaccessTokenfor OAuth2, or set custom headers in client initialization. Some generators have built-in OAuth2 and API key support. - Build the generated project, package it (npm pack, python setup.py sdist, mvn package), and publish to the registry (npm publish, twine upload, mvn deploy). Automate in CI.
- Generated code is deterministic from the spec — the spec is the source of truth. Generated code in git causes merge conflicts, diff noise, and bloat. CI generates it when needed.
Challenge: Write an OpenAPI spec with 6 endpoints and authentication, generate JavaScript, Python, and Swift clients from the same spec, write a test script in each language that authenticates and calls 3 endpoints, and compare the generated code structure across languages.
FAQ
Mini Project
Write an OpenAPI spec with 6 CRUD endpoints, generate clients for JavaScript (fetch), Python (urllib3), and Swift, configure authentication via API key header, write a test script per language that creates, reads, updates, and deletes a resource, and publish one of the clients to a test npm/PyPI registry.
What's Next
API Documentation — generate interactive API documentation from OpenAPI specs.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro