Minimal API Endpoints
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Minimal API Endpoints in the TSZ project provide a lightweight, performance-oriented approach to building HTTP services. Built using .NET's Minimal API paradigm, these endpoints are organized into feature-based modules (e.g., Users, Customers, Contracts) rather than traditional controllers. This structure promotes a clear separation of concerns by delegating business logic to dedicated services while using the endpoint layer primarily for request routing, parameter binding, and response orchestration.
Sources: packages/api/Program.cs, REVIEW.md:46-60
Architectural Overview
The API architecture follows a modular pattern where each functional area of the application is encapsulated within its own module. The Program.cs file acts as the central orchestrator, while specific Map methods in static endpoint classes register the routes.
Module Registration and Mapping
Modules are registered in two phases: service registration and route mapping. Extension methods are used to keep the entry point clean and manageable.
The diagram shows the sequential flow from application startup to module-specific route registration.
Sources: packages/api/Program.cs:22-48
Core Components
Endpoint Groups
Endpoints are organized into logical groups using a helper extension MapApiGroup. This ensures consistent URL prefixing (typically /api/) and allows for common configurations to be applied across all routes within a module.
| Component | Description | Reference File |
|---|---|---|
WebApplication | The main host that routes are mapped to. | Program.cs |
UserEndpoints | Defines routes for user identity and administration. | UserEndpoints.cs |
CustomerEndpoints | Manages customer-related CRUD operations. | CustomerEndpoints.cs |
ContractEndpoints | Handles contract creation and lifecycle management. | ContractEndpoints.cs |
ValidationFilter | An endpoint filter that intercepts requests for validation. | ValidationFilter.cs |
Sources: packages/api/Modules/Users/UserEndpoints.cs:13, packages/api/Modules/Customers/CustomerEndpoints.cs:13
Request Validation
The system utilizes ValidationFilter<T> to enforce data integrity. This filter is attached to POST and PUT endpoints to validate incoming Request Objects (DTOs) before the handler logic executes.
This sequence illustrates how the ValidationFilter acts as a gatekeeper for endpoint handlers.
Sources: packages/api/Modules/Users/UserEndpoints.cs:64-79, packages/api/Common/Filters/ValidationFilter.cs
Standard Endpoint Patterns
CRUD Operations
The modules implement a standard set of CRUD operations (Create, Read, Update, Delete/Archive). Archive operations are typically implemented via PATCH rather than DELETE to support soft-deletion.
Common Endpoint Parameters
Most GET collection endpoints support the following query parameters for pagination and sorting:
search(string?): Optional text search.sort(Enum): Module-specific sort keys.sortDirection(Enum):AscorDesc.page(int): Target page number (defaults to 1).pageSize(int): Items per page (defaults to 25, max 100).
Sources: packages/api/Modules/Users/UserEndpoints.cs:34-45, packages/api/Modules/Contracts/ContractEndpoints.cs:15-28
Response Handling
The project uses TypedResults to provide strongly-typed HTTP responses, improving testability and OpenAPI documentation.
| Response Type | HTTP Status | Usage Scenario |
|---|---|---|
Ok<T> | 200 OK | Successful retrieval or update. |
CreatedAtRoute | 201 Created | Successful creation of a resource. |
NoContent | 204 No Content | Successful completion of an action (e.g., Archive). |
NotFound | 404 Not Found | Resource ID does not exist. |
Problem | 400/409/422 | Validation errors, conflicts, or business rule violations. |
Sources: packages/api/Modules/Users/UserEndpoints.cs:18-100, packages/api/Modules/Contracts/ContractEndpoints.cs:46-60
Implementation Examples
User Provisioning Endpoint
The /me endpoint demonstrates automatic user provisioning based on JWT claims extracted from the HttpContext.
group.MapGet("/me", async Task<Results<Ok<User>, ProblemHttpResult>> (
HttpContext httpContext,
UserService service,
CancellationToken cancellationToken) =>
{
var name = httpContext.User.FindFirst("name")?.Value ?? "";
var email = httpContext.User.FindFirst("preferred_username")?.Value
?? httpContext.User.FindFirst("upn")?.Value
?? httpContext.User.FindFirst("email")?.Value
?? "";
if (string.IsNullOrEmpty(email))
return TypedResults.Problem("No UPN claim in token.", statusCode: 400);
var user = await service.GetOrProvisionAsync(name, email, cancellationToken);
return TypedResults.Ok(user);
});
Sources: packages/api/Modules/Users/UserEndpoints.cs:15-32
Archive/Unarchive Pattern
Resource lifecycle management is handled via PATCH endpoints that toggle an IsArchived status.
group.MapPatch("/{id:guid}/archive", async Task<Results<NoContent, NotFound>> (
Guid id,
UserService service,
CancellationToken cancellationToken) =>
{
return await service.ArchiveAsync(id, cancellationToken)
? TypedResults.NoContent()
: TypedResults.NotFound();
});
Sources: packages/api/Modules/Users/UserEndpoints.cs:83-91, packages/api/Modules/Customers/CustomerEndpoints.cs:57-65
Conclusion
Minimal API Endpoints in the TSZ project provide a streamlined and highly modular interface for frontend consumption. By utilizing static mapping classes, generic validation filters, and strongly-typed results, the API maintains high performance and clear documentation while ensuring that business logic remains decoupled within the service layer. This architecture allows the system to scale effectively as new modules are introduced.