Examples and Use Cases
This section provides practical examples of using the Albatross CodeGen Framework in real-world scenarios.
Basic Examples
Simple Controller Generation
Given this ASP.NET Core controller:
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet]
public async Task<ActionResult<List<User>>> GetUsers()
{
// Implementation
}
[HttpGet("{id}")]
public async Task<ActionResult<User>> GetUser(int id)
{
// Implementation
}
[HttpPost]
public async Task<ActionResult<User>> CreateUser(CreateUserRequest request)
{
// Implementation
}
}
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
}
public class CreateUserRequest
{
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
Generated TypeScript Client
Command:
codegen typescript web-client -p MyWebApi.csproj -o ./generated/typescript
Generated files:
models/user.ts:
export interface User {
id: number;
name: string;
email: string;
createdAt: Date;
}
export interface CreateUserRequest {
name: string;
email: string;
}
clients/users-client.ts:
import { User, CreateUserRequest } from '../models/user';
export class UsersClient {
constructor(private baseUrl: string = '') {}
async getUsers(): Promise<User[]> {
const response = await fetch(`${this.baseUrl}/api/users`);
return await response.json();
}
async getUser(id: number): Promise<User> {
const response = await fetch(`${this.baseUrl}/api/users/${id}`);
return await response.json();
}
async createUser(request: CreateUserRequest): Promise<User> {
const response = await fetch(`${this.baseUrl}/api/users`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request)
});
return await response.json();
}
}
Generated Python Client
Command:
codegen python web-client -p MyWebApi.csproj -o ./generated/python
models/user.py:
from dataclasses import dataclass
from datetime import datetime
from typing import Optional
@dataclass
class User:
id: int
name: str
email: str
created_at: datetime
@dataclass
class CreateUserRequest:
name: str
email: str
clients/users_client.py:
import aiohttp
from typing import List
from ..models.user import User, CreateUserRequest
class UsersClient:
def __init__(self, base_url: str = ""):
self.base_url = base_url
async def get_users(self) -> List[User]:
async with aiohttp.ClientSession() as session:
async with session.get(f"{self.base_url}/api/users") as response:
data = await response.json()
return [User(**item) for item in data]
async def get_user(self, id: int) -> User:
async with aiohttp.ClientSession() as session:
async with session.get(f"{self.base_url}/api/users/{id}") as response:
data = await response.json()
return User(**data)
async def create_user(self, request: CreateUserRequest) -> User:
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.base_url}/api/users",
json=request.__dict__
) as response:
data = await response.json()
return User(**data)
Advanced Examples
Complex Types with Inheritance
Source C# Models:
public abstract class BaseEntity
{
public int Id { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public class Product : BaseEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public ProductCategory Category { get; set; }
}
public enum ProductCategory
{
Electronics,
Clothing,
Books,
Home
}
public class ProductWithReviews : Product
{
public List<Review> Reviews { get; set; } = new();
public double AverageRating { get; set; }
}
public class Review
{
public int Id { get; set; }
public int ProductId { get; set; }
public string ReviewerName { get; set; } = string.Empty;
public int Rating { get; set; }
public string Comment { get; set; } = string.Empty;
}
Generated TypeScript with Inheritance:
export interface BaseEntity {
id: number;
createdAt: Date;
updatedAt: Date;
}
export enum ProductCategory {
Electronics = 0,
Clothing = 1,
Books = 2,
Home = 3
}
export interface Product extends BaseEntity {
name: string;
price: number;
category: ProductCategory;
}
export interface Review {
id: number;
productId: number;
reviewerName: string;
rating: number;
comment: string;
}
export interface ProductWithReviews extends Product {
reviews: Review[];
averageRating: number;
}
Generic Types
Source C# Controller:
[ApiController]
public class GenericController<T> : ControllerBase where T : BaseEntity
{
[HttpGet]
public async Task<PagedResult<T>> GetPaged(
int page = 1,
int pageSize = 10,
string? search = null)
{
// Implementation
}
}
public class PagedResult<T>
{
public List<T> Items { get; set; } = new();
public int TotalCount { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
public bool HasNext => Page * PageSize < TotalCount;
public bool HasPrevious => Page > 1;
}
Generated TypeScript:
export interface PagedResult<T> {
items: T[];
totalCount: number;
page: number;
pageSize: number;
hasNext: boolean;
hasPrevious: boolean;
}
export class GenericClient<T extends BaseEntity> {
constructor(private baseUrl: string, private endpoint: string) {}
async getPaged(
page: number = 1,
pageSize: number = 10,
search?: string
): Promise<PagedResult<T>> {
const params = new URLSearchParams();
params.append('page', page.toString());
params.append('pageSize', pageSize.toString());
if (search) params.append('search', search);
const response = await fetch(`${this.baseUrl}/${this.endpoint}?${params}`);
return await response.json();
}
}
Custom Configuration Example
Settings File (codegen.json):
{
"namespace": "MyCompany.ApiClients",
"includePatterns": ["*Controller"],
"excludePatterns": ["*TestController", "*AdminController"],
"typeMapping": {
"System.Guid": "string",
"System.DateTimeOffset": "Date"
},
"templates": {
"fileHeader": "/* eslint-disable */\n// Auto-generated by Albatross CodeGen\n// Date: {{date}}\n",
"classHeader": "/**\n * {{summary}}\n * Generated from: {{sourceType}}\n */"
},
"validation": {
"requireDocumentation": true,
"warnOnMissingTypes": false
}
}
Usage:
codegen typescript web-client -p MyWebApi.csproj -s codegen.json -o ./src/generated
Integration Examples
Build Pipeline Integration
MSBuild Integration (.csproj):
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<Target Name="GenerateClients" BeforeTargets="Build">
<Exec Command="codegen typescript web-client -p $(MSBuildProjectFile) -o ./ClientApp/src/generated" />
</Target>
</Project>
GitHub Actions Workflow:
name: Generate API Clients
on:
push:
branches: [ main, develop ]
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Install CodeGen Tool
run: dotnet tool install --global Albatross.CodeGen.CommandLine
- name: Generate TypeScript Client
run: codegen typescript web-client -p MyWebApi.csproj -o ./frontend/src/generated
- name: Generate Python Client
run: codegen python web-client -p MyWebApi.csproj -o ./python-client/src/generated
- name: Commit generated files
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add ./frontend/src/generated ./python-client/src/generated
git diff --staged --quiet || git commit -m "Update generated API clients"
git push
Docker Integration
Dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
# Install CodeGen tool
RUN dotnet tool install --global Albatross.CodeGen.CommandLine
ENV PATH="${PATH}:/root/.dotnet/tools"
# Copy source and generate clients
COPY . /src
WORKDIR /src
RUN dotnet build MyWebApi.csproj
RUN codegen typescript web-client -p MyWebApi.csproj -o ./generated/typescript
RUN codegen python web-client -p MyWebApi.csproj -o ./generated/python
# Continue with application build...
Best Practices Examples
Organizing Generated Code
Recommended Structure:
src/
├── generated/ # All generated code
│ ├── typescript/
│ │ ├── models/ # Data models
│ │ ├── clients/ # API clients
│ │ └── index.ts # Barrel exports
│ ├── python/
│ │ ├── models/
│ │ ├── clients/
│ │ └── __init__.py
│ └── csharp/
│ ├── Models/
│ └── Clients/
├── custom/ # Custom code
└── app/ # Application code
Error Handling Patterns
Generated TypeScript with Error Handling:
export class ApiError extends Error {
constructor(public status: number, message: string, public response?: any) {
super(message);
}
}
export class UsersClient {
async getUser(id: number): Promise<User> {
const response = await fetch(`${this.baseUrl}/api/users/${id}`);
if (!response.ok) {
const errorData = await response.text();
throw new ApiError(response.status, response.statusText, errorData);
}
return await response.json();
}
}
These examples demonstrate the flexibility and power of the Albatross CodeGen Framework across various scenarios and integration patterns.