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 specificationresources/- Endpoint definitions by domainschemas/- Reusable data modelsparameters/- 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, orgo.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
$reffor 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
- Fork the repository
- Create a feature branch
- Make your changes
- Test with
task all - 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.