Auto-Generating SDKs from OpenAPI Specs

Meta Description: Generate client SDKs automatically from OpenAPI specs. Learn tools, best practices, and how to maintain type-safe SDKs for multiple languages. Keywords: sdk generation, openapi sdk, api client generation, openapi generator, type-safe sdk, client libraries Word Count: ~2,300 words You've built an API. Now developers need client libraries

TRY NANO BANANA FOR FREE

Auto-Generating SDKs from OpenAPI Specs

TRY NANO BANANA FOR FREE
Contents

Meta Description: Generate client SDKs automatically from OpenAPI specs. Learn tools, best practices, and how to maintain type-safe SDKs for multiple languages.

Keywords: sdk generation, openapi sdk, api client generation, openapi generator, type-safe sdk, client libraries

Word Count: ~2,300 words


You've built an API. Now developers need client libraries for JavaScript, Python, Go, Java, and more.

Writing SDKs manually is time-consuming. Every API change requires updating multiple SDKs. Documentation gets out of sync.

Auto-generate SDKs from your OpenAPI specification instead.

Why Auto-Generate SDKs?

Consistency

Generated SDKs match your API exactly. No manual translation errors.

Maintenance

Update your OpenAPI spec, regenerate SDKs. All clients stay in sync.

Type Safety

Generated SDKs include types from your OpenAPI schemas. Catch errors at compile time.

Documentation

SDKs include inline documentation from your OpenAPI descriptions.

Multi-Language Support

Generate SDKs for 20+ languages from one specification.

OpenAPI Generator

OpenAPI Generator is the most popular tool for SDK generation.

Installation

npm install -g @openapitools/openapi-generator-cli

Or use Docker:

docker pull openapitools/openapi-generator-cli

Generate JavaScript SDK

openapi-generator-cli generate \
  -i openapi.yaml \
  -g javascript \
  -o ./sdks/javascript \
  --additional-properties=projectName=petstore-sdk,projectVersion=1.0.0

This creates a complete JavaScript SDK with: - API client classes - Model classes - TypeScript definitions - README with examples - Package.json

Generate Python SDK

openapi-generator-cli generate \
  -i openapi.yaml \
  -g python \
  -o ./sdks/python \
  --additional-properties=packageName=petstore_sdk,packageVersion=1.0.0

Generate Go SDK

openapi-generator-cli generate \
  -i openapi.yaml \
  -g go \
  -o ./sdks/go \
  --additional-properties=packageName=petstore

Supported Languages

OpenAPI Generator supports 50+ languages and frameworks: - JavaScript/TypeScript - Python - Go - Java - C# - Ruby - PHP - Swift - Kotlin - Rust - And many more

Using Generated SDKs

JavaScript/TypeScript

import { PetStoreApi, Configuration } from 'petstore-sdk';

const config = new Configuration({
  basePath: 'https://api.petstoreapi.com/v1',
  accessToken: 'your-api-key'
});

const api = new PetStoreApi(config);

// Get a pet
const pet = await api.getPet({ id: '123' });
console.log(pet.name);

// Create a pet
const newPet = await api.createPet({
  createPetRequest: {
    name: 'Max',
    species: 'DOG',
    breed: 'Golden Retriever'
  }
});

// List pets with filters
const pets = await api.listPets({
  species: 'DOG',
  status: 'AVAILABLE',
  limit: 20
});

Python

from petstore_sdk import PetStoreApi, Configuration

config = Configuration(
    host='https://api.petstoreapi.com/v1',
    access_token='your-api-key'
)

api = PetStoreApi(config)

# Get a pet
pet = api.get_pet(id='123')
print(pet.name)

# Create a pet
new_pet = api.create_pet(
    create_pet_request={
        'name': 'Max',
        'species': 'DOG',
        'breed': 'Golden Retriever'
    }
)

# List pets with filters
pets = api.list_pets(
    species='DOG',
    status='AVAILABLE',
    limit=20
)

Go

package main

import (
    "context"
    "fmt"
    petstore "github.com/yourorg/petstore-sdk-go"
)

func main() {
    config := petstore.NewConfiguration()
    config.Host = "api.petstoreapi.com"
    config.Scheme = "https"
    config.AddDefaultHeader("Authorization", "Bearer your-api-key")

    client := petstore.NewAPIClient(config)

    // Get a pet
    pet, _, err := client.PetsApi.GetPet(context.Background(), "123").Execute()
    if err != nil {
        panic(err)
    }
    fmt.Println(pet.Name)

    // Create a pet
    newPet := petstore.NewCreatePetRequest("Max", "DOG")
    newPet.SetBreed("Golden Retriever")

    created, _, err := client.PetsApi.CreatePet(context.Background()).
        CreatePetRequest(*newPet).
        Execute()
    if err != nil {
        panic(err)
    }
}

Customizing Generated SDKs

Configuration File

Create config.yaml:

generatorName: typescript-fetch
inputSpec: openapi.yaml
outputDir: ./sdks/typescript
additionalProperties:
  npmName: "@yourorg/petstore-sdk"
  npmVersion: "1.0.0"
  supportsES6: true
  withInterfaces: true
  useSingleRequestParameter: true

Generate with config:

openapi-generator-cli generate -c config.yaml

Custom Templates

Override default templates:

openapi-generator-cli generate \
  -i openapi.yaml \
  -g typescript-fetch \
  -o ./sdks/typescript \
  -t ./templates/typescript

Create templates/typescript/api.mustache to customize API class generation.

Post-Processing

Add custom code after generation:

#!/bin/bash

# Generate SDK
openapi-generator-cli generate -i openapi.yaml -g javascript -o ./sdk

# Add custom utilities
cp ./custom/utils.js ./sdk/src/utils.js

# Update package.json
jq '.scripts.test = "jest"' ./sdk/package.json > ./sdk/package.json.tmp
mv ./sdk/package.json.tmp ./sdk/package.json

# Install dependencies and build
cd ./sdk
npm install
npm run build

Best Practices

1. Version Your SDKs

Match SDK versions to API versions:

# openapi.yaml
info:
  version: "1.2.0"

Generate with version:

openapi-generator-cli generate \
  -i openapi.yaml \
  -g python \
  --additional-properties=packageVersion=1.2.0

2. Include Examples in OpenAPI

Examples become SDK documentation:

paths:
  /pets:
    post:
      summary: Create a pet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePetRequest'
            examples:
              dog:
                summary: Create a dog
                value:
                  name: "Max"
                  species: "DOG"
                  breed: "Golden Retriever"

Generated SDK includes this example in documentation.

3. Use Descriptive Names

Good OpenAPI names become good SDK names:

# Bad
paths:
  /p:
    get:
      operationId: gp

# Good
paths:
  /pets:
    get:
      operationId: listPets

4. Add Descriptions

Descriptions become SDK comments:

paths:
  /pets/{id}:
    get:
      summary: Get a pet by ID
      description: |
        Retrieves detailed information about a specific pet.
        Requires read:pets permission.
      parameters:
        - name: id
          in: path
          description: The unique identifier of the pet
          required: true
          schema:
            type: string
            format: uuid

Generated SDK:

/**
 * Get a pet by ID
 *
 * Retrieves detailed information about a specific pet.
 * Requires read:pets permission.
 *
 * @param id The unique identifier of the pet
 */
async getPet(id: string): Promise<Pet>

5. Automate SDK Publishing

# .github/workflows/publish-sdks.yml
name: Publish SDKs

on:
  release:
    types: [published]

jobs:
  publish-javascript:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Generate JavaScript SDK
        run: |
          openapi-generator-cli generate \
            -i openapi.yaml \
            -g javascript \
            -o ./sdk

      - name: Publish to npm
        run: |
          cd ./sdk
          npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

  publish-python:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Generate Python SDK
        run: |
          openapi-generator-cli generate \
            -i openapi.yaml \
            -g python \
            -o ./sdk

      - name: Publish to PyPI
        run: |
          cd ./sdk
          python setup.py sdist
          twine upload dist/*
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}

Alternative Tools

Swagger Codegen

Predecessor to OpenAPI Generator:

swagger-codegen generate \
  -i openapi.yaml \
  -l javascript \
  -o ./sdk

OpenAPI TypeScript

TypeScript-specific generator:

npx openapi-typescript openapi.yaml --output ./types.ts

Generates TypeScript types only (no runtime code).

Orval

React Query + Axios generator:

npx orval --input openapi.yaml --output ./src/api

Generates React hooks for API calls.

Fern

Modern SDK generator with better customization:

fern generate --api openapi.yaml --language typescript

Testing Generated SDKs

Unit Tests

// test/pets.test.js
import { PetStoreApi } from '../sdk';

describe('PetsApi', () => {
  let api;

  beforeEach(() => {
    api = new PetStoreApi({
      basePath: 'http://localhost:3000',
      accessToken: 'test-key'
    });
  });

  test('getPet returns pet data', async () => {
    const pet = await api.getPet({ id: '123' });
    expect(pet.name).toBe('Max');
    expect(pet.species).toBe('DOG');
  });

  test('createPet creates a new pet', async () => {
    const newPet = await api.createPet({
      createPetRequest: {
        name: 'Bella',
        species: 'CAT'
      }
    });
    expect(newPet.id).toBeDefined();
  });
});

Integration Tests

// test/integration.test.js
import { PetStoreApi } from '../sdk';

describe('Integration Tests', () => {
  const api = new PetStoreApi({
    basePath: process.env.API_URL,
    accessToken: process.env.API_KEY
  });

  test('full pet lifecycle', async () => {
    // Create
    const created = await api.createPet({
      createPetRequest: { name: 'Test Pet', species: 'DOG' }
    });

    // Read
    const fetched = await api.getPet({ id: created.id });
    expect(fetched.name).toBe('Test Pet');

    // Update
    const updated = await api.updatePet({
      id: created.id,
      updatePetRequest: { name: 'Updated Pet' }
    });
    expect(updated.name).toBe('Updated Pet');

    // Delete
    await api.deletePet({ id: created.id });
  });
});

Maintaining SDKs

Versioning Strategy

Semantic Versioning: - Major: Breaking API changes - Minor: New features (backward compatible) - Patch: Bug fixes

Match API versions:

API v1.2.3 → SDK v1.2.3

Changelog

Generate changelogs from OpenAPI changes:

# Compare OpenAPI specs
openapi-diff old-openapi.yaml new-openapi.yaml > CHANGELOG.md

Deprecation Warnings

Mark deprecated endpoints in OpenAPI:

paths:
  /pets/findByStatus:
    get:
      deprecated: true
      summary: Find pets by status (deprecated)
      description: Use GET /pets?status=AVAILABLE instead

Generated SDK includes deprecation warnings.


Auto-generating SDKs from OpenAPI specifications saves time, ensures consistency, and improves developer experience. Start with OpenAPI Generator, customize as needed, and automate publishing for seamless SDK maintenance.

Your developers get type-safe, well-documented client libraries that stay in sync with your API automatically.