Skip to content
davidkallesen edited this page May 28, 2026 · 10 revisions

🏠 Atc.Rest.Api.SourceGenerator

A Roslyn Source Generator that automatically generates REST API server and client code from OpenAPI specifications. No CLI commands, no manual code generation - just build your project and get production-ready code.

✨ Key Features

Area Feature Description
Core πŸ”§ Zero Configuration Add the NuGet package, drop your YAML file, build
πŸ—οΈ Minimal API Generates modern ASP.NET Core minimal API endpoints
πŸ”’ Contract-Enforced Results Handlers can only return responses defined in OpenAPI - compile-time safety!
βœ… Validation Automatic [Required], [Range], [StringLength] from OpenAPI constraints
Server πŸ“ Handler Scaffolds Auto-generates handler stubs for unimplemented operations
πŸ” Security JWT, OAuth2 scopes, API Key, role-based auth - all from OpenAPI
⏱️ Rate Limiting Server-side rate limiting from x-ratelimit-* extensions
πŸ’Ύ Caching Output caching and HybridCache support from x-cache-* extensions
Client πŸ”Œ Type-Safe Client Strongly-typed HTTP client with full IntelliSense
πŸ”„ Resilience Client-side retry/circuit breaker from x-retry-* extensions
πŸ”— URL Encoding Automatic RFC 3986 compliant encoding - no more broken URLs
Models 🎯 Enum Support Generates C# enums from OpenAPI string enums
πŸ“Š Pagination Generic PaginatedResult<T> from allOf composition
Data πŸ“ File Uploads Full support for binary uploads (single, multiple, with metadata)
🌊 Streaming IAsyncEnumerable<T> support for efficient data streaming
CLI πŸ–₯️ Project Scaffolding generate server / generate client creates complete project structure
🟦 TypeScript Client generate client-typescript β€” Fetch/Axios, interceptors, retry, MSW handlers
βš›οΈ React Hooks React Query (useQuery/useMutation/useInfiniteQuery/useSuspenseQuery) + SWR β€” streaming hooks for IAsyncEnumerable
πŸͺͺ Branded ID types --branded-ids emits nominal types β€” getUser(petId) becomes a compile error
πŸ” Runtime Zod validation --zod-runtime-validate wires Zod into response parsing β€” spec-drift detection
πŸ”Œ SignalR Hub Hooks x-signalr-hubs extension β†’ typed use<Hub>Hub() with auto-reconnect
πŸ“‹ Spec Validation spec validate validates OpenAPI specs with strict/standard modes
πŸ”— Multi-Part Specs spec merge / spec split for large API specifications
βš™οΈ Options Management options create / options validate for configuration files
πŸ”„ Migration migrate validate / migrate execute to migrate from old CLI generator

⚑ Quick Start

1️⃣ Install the Package

dotnet add package Atc.Rest.Api.SourceGenerator

2️⃣ Add Your OpenAPI Spec

Add your *.yaml file and marker file to .csproj:

<ItemGroup>
  <AdditionalFiles Include="MyApi.yaml" />
  <AdditionalFiles Include=".atc-rest-api-server" />
</ItemGroup>

3️⃣ Create Marker File

Create .atc-rest-api-server:

{
  "generate": true,
  "validateSpecificationStrategy": "Standard"
}

4️⃣ Build and Use

dotnet build

Generated code includes:

  • πŸ“¦ Models - C# records with validation attributes
  • 🎯 Handler Interfaces - IListPetsHandler, ICreatePetHandler, etc.
  • πŸ›£οΈ Endpoints - Minimal API MapGet, MapPost, etc.
  • πŸ’‰ DI Extensions - AddApiHandlersFromDomain(), MapApiEndpoints()

πŸ’‘ Tip: Use the CLI tool to scaffold complete projects automatically!

dotnet tool install -g atc-rest-api-gen
atc-rest-api-gen generate server -s api.yaml -o ./my-api -n MyApi

See Getting Started with CLI for a complete walkthrough.

πŸ”„ Migrating from the old CLI generator? Use the built-in migration tool:

atc-rest-api-gen migrate validate -s ./my-project -p api.yaml
atc-rest-api-gen migrate execute -s ./my-project -p api.yaml

See Migration Guide for step-by-step instructions.

πŸ“‹ Requirements

  • .NET 10 or later
  • OpenAPI 3.0.x or 3.1.x specification

πŸ—οΈ Architecture

The project uses a three-layer architecture:

Layer Project Description
πŸ“¦ Shared Atc.Rest.Api.Generator All extractors, services, configuration, validation (Roslyn-independent)
βš™οΈ Generators Atc.Rest.Api.SourceGenerator Roslyn source generators (thin wrappers calling shared services)
πŸ› οΈ CLI Atc.Rest.Api.Generator.Cli Command-line tool for validation and generation

πŸ’‘ Example: Type-Safe Results

public class GetPetByIdHandler : IGetPetByIdHandler
{
    public async Task<GetPetByIdResult> ExecuteAsync(
        GetPetByIdParameters parameters,
        CancellationToken ct)
    {
        var pet = await repository.GetByIdAsync(parameters.PetId, ct);

        // βœ… Clean syntax with implicit operator
        if (pet is not null)
            return pet;  // Implicitly converts to GetPetByIdResult.Ok(pet)

        // βœ… Factory methods for error responses
        return GetPetByIdResult.NotFound();

        // ❌ COMPILE ERROR - Method doesn't exist!
        // return GetPetByIdResult.InternalServerError();
    }
}

πŸ”’ Type-Safe Results: Result classes have private constructors and factory methods matching your OpenAPI responses. You literally cannot return a status code that isn't in your spec!

🏷️ Marker Files

File Purpose
.atc-rest-api-server Server code (models, endpoints, handlers)
.atc-rest-api-server-handlers Handler implementation scaffolds
.atc-rest-api-client HTTP client generation

πŸ“œ License

MIT License - see LICENSE for details.

🏠 Home

πŸ’Ό Why This Tool?

πŸ“– Getting Started

βš™οΈ Features

🌐 Frontend

πŸ“‹ Reference


πŸ”— Resources

Clone this wiki locally