-
Notifications
You must be signed in to change notification settings - Fork 1
Working with Endpoint Definitions
This guide explains the IEndpointDefinition pattern used by the generated minimal API endpoints.
The source generator creates structured endpoint definitions that implement the IEndpointDefinition interface. Each path segment gets its own definition class with route mapping, parameter binding, and OpenAPI metadata. All definition classes are emitted side by side in the shared Endpoints folder and namespace, since their type names are already segment-prefixed.
For an API with /pets and /users path segments:
Generated/
βββ Endpoints/
βββ IEndpointDefinition.cs # Shared interface
βββ PetsEndpointDefinition.cs
βββ UsersEndpointDefinition.cs
βββ EndpointDefinitionExtensions.cs # One Map{Segment}Endpoints() per segment
βββ EndpointMappingExtensions.cs # MapApiEndpoints() β maps all segments
Generated once in the shared Endpoints namespace:
namespace MyApi.Generated.Endpoints;
[GeneratedCode("Atc.Rest.Api.SourceGenerator", "1.0.0")]
public interface IEndpointDefinition
{
void DefineEndpoints(WebApplication app);
}Each path segment gets a definition class, all sharing the root Endpoints namespace:
namespace MyApi.Generated.Endpoints;
[GeneratedCode("Atc.Rest.Api.SourceGenerator", "1.0.0")]
public sealed class PetsEndpointDefinition : IEndpointDefinition
{
internal const string ApiRouteBase = "/pets";
public void DefineEndpoints(WebApplication app)
{
var pets = app
.MapGroup(ApiRouteBase)
.WithTags("Pets");
pets
.MapGet("/", ListPets)
.WithName("ListPets")
.WithSummary("List all pets")
.Produces<List<Pet>>()
.ProducesValidationProblem();
pets
.MapGet("{petId}", GetPetById)
.WithName("GetPetById")
.WithSummary("Get a pet by ID")
.Produces<Pet>()
.ProducesProblem(StatusCodes.Status404NotFound);
pets
.MapPost("/", CreatePet)
.WithName("CreatePet")
.WithSummary("Create a pet")
.Produces<Pet>(StatusCodes.Status201Created)
.ProducesValidationProblem();
}
internal async Task<IResult> ListPets(
[FromServices] IListPetsHandler handler,
[AsParameters] ListPetsParameters parameters,
CancellationToken cancellationToken)
=> ListPetsResult.ToIResult(
await handler.ExecuteAsync(parameters, cancellationToken));
internal async Task<IResult> GetPetById(
[FromServices] IGetPetByIdHandler handler,
[AsParameters] GetPetByIdParameters parameters,
CancellationToken cancellationToken)
=> GetPetByIdResult.ToIResult(
await handler.ExecuteAsync(parameters, cancellationToken));
// ... more endpoint methods ...
}Two extension classes are generated, both in the root Endpoints namespace.
EndpointDefinitionExtensions exposes one Map{Segment}Endpoints() method per path segment, each instantiating that segment's definition class:
public static class EndpointDefinitionExtensions
{
public static WebApplication MapPetsEndpoints(this WebApplication app)
{
new PetsEndpointDefinition().DefineEndpoints(app);
return app;
}
public static WebApplication MapUsersEndpoints(this WebApplication app)
{
new UsersEndpointDefinition().DefineEndpoints(app);
return app;
}
}EndpointMappingExtensions aggregates them into the single entry point you call from Program.cs:
public static class EndpointMappingExtensions
{
public static WebApplication MapApiEndpoints(this WebApplication app)
{
app.MapPetsEndpoints();
app.MapUsersEndpoints();
return app;
}
}π‘ Call
MapApiEndpoints()to register everything, or call an individualMap{Segment}Endpoints()when you need to map only part of the API.
Controls where the IEndpointDefinition interface comes from:
{
"useMinimalApiPackage": "auto"
}| Value | Behavior |
|---|---|
"auto" |
Use Atc.Rest.MinimalApi package if referenced, otherwise generate locally (default) |
"enabled" |
Always use from Atc.Rest.MinimalApi NuGet package (error if not referenced) |
"disabled" |
Always generate the interface locally |
Adds FluentValidation filter to endpoint definitions:
{
"useMinimalApiPackage": "enabled",
"useValidationFilter": "enabled"
}When enabled, endpoint definitions include .AddEndpointFilter<ValidationFilter<T>>() for request validation.
var builder = WebApplication.CreateBuilder(args);
// Register handlers from Domain project
builder.Services.AddApiHandlersFromDomain();
var app = builder.Build();
// Map all generated endpoints
app.MapApiEndpoints();
app.Run();Since all definition classes implement the shared IEndpointDefinition interface, you can collect and apply them dynamically:
// Discover and register all endpoint definitions
var endpointDefinitions = typeof(PetsEndpointDefinition).Assembly
.GetTypes()
.Where(t => typeof(IEndpointDefinition).IsAssignableFrom(t) && !t.IsInterface)
.Select(Activator.CreateInstance)
.Cast<IEndpointDefinition>();
foreach (var definition in endpointDefinitions)
{
definition.DefineEndpoints(app);
}The subFolderStrategy setting controls how operations are grouped into endpoint definitions:
| Strategy | Grouping | Example |
|---|---|---|
"FirstPathSegment" (default) |
By first path segment |
/pets/* -> PetsEndpointDefinition
|
"OpenApiTag" |
By OpenAPI operation tag | Tag pets -> PetsEndpointDefinition
|
{
"subFolderStrategy": "FirstPathSegment"
}- Getting Started with Basic β Create your first project
- Working with Validations β Add FluentValidation
- Working with Versioning β Version your endpoints
- Marker Files β Full configuration reference
π Home
- πΌ FAQ Business Value
- π Getting Started with Basic
- π οΈ Getting Started with CLI
- π Migration Guide
- β¬οΈ Upgrading to v2
- π Working with OpenAPI
- π³οΈ Working with Nullability
- π οΈ Working with CLI
- π How-To Guides
- π Working with Security
- π¦ Working with Rate Limiting
- π Working with Resilience
- ποΈ Working with Caching
- π’ Working with Versioning
- β Working with Validations
- π Working with Webhooks
- βοΈ Working with Aspire
- π£οΈ Working with Endpoint Definitions
- π Working with Multi-Part Specs
- π§ͺ Working with Code Coverage
- π Working with C# Client
- π§ͺ Working with C# Client Testing
- π¦ Working with TypeScript Client
- πͺ Showcase Demo
- π§ͺ Working with E2E Testing
- βοΈ Working with Configuration
- π Marker Files
- π API Reference
- π Analyzer Rules
- β FAQ and Troubleshooting
- πΊοΈ Roadmap
- π§ Development Notes
- π¦ GitHub Repository
- π₯ NuGet Package
- π Report Issues