openapi-forge

module
v0.0.0-...-5eda2ce Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2025 License: MIT

README ΒΆ

OpenAPI Forge

A template for creating API contract repositories with Clean Architecture principles, enabling multi-language code generation for Go, Python, and TypeScript from a single API specification.

🎯 This is a blueprint/template - copy it to create your own API contracts repository!

🎯 Purpose

OpenAPI Forge demonstrates how to build enterprise-grade API tooling with:

  • Clean Architecture separation of concerns
  • Multi-language code generation from single source of truth
  • Developer-friendly project structure and workflows
  • Production-ready generated adapters

πŸš€ Quick Start

1. Create Your API Contracts Repository
# Use this repository as a template for your own API contracts
git clone https://github.com/eoncell/openapi-forge.git my-api-contracts
cd my-api-contracts

# Make it your own repository
rm -rf .git
git init
git remote add origin https://github.com/mycompany/my-api-contracts.git

# Install dependencies
task install
2. Design Your API
# πŸ‘ˆ 🟒 **WORK HERE**: Customize the API specifications for your domain
vim api/resources/users/users.yaml
vim api/schemas/users/User.yaml

# πŸ”§ 🟒 **HANDS-OFF**: Generate adapters from your specifications
task generate

# πŸ“¦ 🟒 **IMPORT THESE**: Verify everything works
ls adapters/go/
ls adapters/python/
ls adapters/typescript/
3. Publish Your Contracts
# Commit and publish your API contracts
git add .
git commit -m "feat: initial API contracts"
git push origin main

# Tag a version for consumption
git tag v1.0.0
git push origin v1.0.0

πŸ“¦ Using Your Contracts in Projects

Now that you've published your contracts, here's how to import them in your services:

Go Service
// go.mod
module github.com/mycompany/user-service

require (
    github.com/mycompany/my-api-contracts/adapters/go v1.0.0
)

// main.go
import (
    "github.com/mycompany/my-api-contracts/adapters/go"
    "github.com/go-chi/chi/v5"
)

func main() {
    server := &MyServer{}
    r := chi.NewRouter()
    contracts.HandlerFromMux(server, r)
    http.ListenAndServe(":8080", r)
}
Python Service
# requirements.txt
git+https://github.com/mycompany/my-api-contracts.git@v1.0.0#subdirectory=adapters/python

# main.py
from adapters.python.models import User, UserCreateRequest
from adapters.python.server.src.contracts.apis.users_api_base import BaseUsersApi

class UsersService(BaseUsersApi):
    def get_users(self, limit: int = 10, offset: int = 0):
        # Your implementation
        pass
TypeScript Client
// package.json
{
  "dependencies": {
    "my-api-contracts": "github:mycompany/my-api-contracts#v1.0.0"
  }
}

// app.ts
import { UsersService } from 'my-api-contracts/adapters/typescript/client';
import type { User } from 'my-api-contracts/adapters/typescript/types';

const users: User[] = await UsersService.getUserList();

πŸ—οΈ Project Structure

openapi-forge/
β”œβ”€β”€ api/                   # API specifications (Domain Layer) πŸ‘ˆ YOU WORK HERE [make changes here then run task]
β”‚   β”œβ”€β”€ openapi.yaml       # Main OpenAPI spec
β”‚   β”œβ”€β”€ parameters/        # Reusable parameters
β”‚   β”œβ”€β”€ resources/         # API endpoint definitions
β”‚   └── schemas/           # Data models and schemas
β”œβ”€β”€ generators/            # Code generators (Application Layer) πŸ”§ HANDS-OFF [mostly]
β”‚   β”œβ”€β”€ go/               
β”‚   β”œβ”€β”€ python/           
β”‚   └── typescript/       
β”œβ”€β”€ adapters/              # Generated API πŸ‘ˆ YOU IMPORT THESE [to your project]
β”‚   β”œβ”€β”€ go/              
β”‚   β”œβ”€β”€ python/          
β”‚   └── typescript/      
β”œβ”€β”€ openapi/               # Bundled OpenAPI spec
β”œβ”€β”€ package.json           # Core tooling (Redocly, Spectral)
└── Taskfile.yml           # Build automation
api/ - API Specifications (Domain Layer) πŸ‘ˆ You work here!
  • openapi.yaml - Main API specification
  • resources/ - Endpoint definitions by domain
  • schemas/ - Reusable data models
  • parameters/ - Shared parameters

πŸ’‘ Primary workspace: This is where you design and customize your API specifications.

generators/ - Code Generators (Application Layer) πŸ”§ Mostly hands-off

Language-specific toolchains with isolated dependencies:

  • Go: oapi-codegen v2 with Chi router β†’ Server interfaces, models, middleware
  • Python: datamodel-code-generator + openapi-generator β†’ FastAPI server, Pydantic models
  • TypeScript: @hey-api/openapi-ts β†’ Fetch client, complete type definitions

⚠️ Implementation details: You rarely need to modify these. The only common change is updating dependency versions in requirements.txt, package.json, or go.mod.

adapters/ - Generated Adapters (Infrastructure Layer) πŸ“¦ You import these
  • Production-ready code generated from specifications
  • Import these as packages in your services/applications
πŸ› οΈ Root Configuration
File Purpose
πŸ“„ Taskfile.yml Build automation and task orchestration
πŸ“„ package.json Core tooling (Redocly, Spectral)
πŸ“„ .spectral.yaml API linting rules

πŸ”§ Available Tasks

# Core Development
task install       # Install all dependencies
task build         # Bundle OpenAPI spec to openapi/openapi.yaml
task generate      # Generate code for all languages
task lint          # Lint OpenAPI specification
task clean         # Remove generated files

# Language-Specific Generation  
task generate-go        # Generate Go models and server
task generate-python    # Generate Python models and server
task generate-typescript # Generate TypeScript client and types

# Full Pipeline
task all           # Complete build: install β†’ build β†’ generate β†’ lint

🎯 Best Practices

Schema Design
  • βœ… Use $ref for reusability
  • βœ… Keep schemas atomic and focused
  • βœ… Organize by domain, not by type
  • βœ… Include examples in schemas
Development Workflow
  • βœ… Work in api/ directory - Design your API specifications
  • βœ… Run task generate - Generate adapters automatically
  • βœ… Import adapters as packages - Use in your services (not copy!)
  • βœ… Rarely touch generators/ - Only for dependency version updates
Versioning
  • βœ… Version your API specifications
  • βœ… Tag releases after breaking changes
  • βœ… Update all consuming services

πŸš€ Benefits

  • Single Source of Truth: API contract drives all implementations
  • Type Safety: Generated code provides compile-time validation
  • Consistency: Same business logic across all language implementations
  • Maintainability: Changes in API automatically propagate to all clients/servers

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test with task all
  5. Submit a pull request

πŸ“œ License

MIT License - see LICENSE file for details.


⭐ Star this repo if you find it helpful!

πŸ’¬ Questions? Open an issue or start a discussion.

πŸ› Found a bug? Please report it with details to reproduce.

Directories ΒΆ

Path Synopsis
adapters
go
Package contracts provides primitives to interact with the openapi HTTP API.
Package contracts provides primitives to interact with the openapi HTTP API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL