Moclawr.MinimalAPI
2.1.3
See the version list below for details.
dotnet add package Moclawr.MinimalAPI --version 2.1.3
NuGet\Install-Package Moclawr.MinimalAPI -Version 2.1.3
<PackageReference Include="Moclawr.MinimalAPI" Version="2.1.3" />
<PackageVersion Include="Moclawr.MinimalAPI" Version="2.1.3" />
<PackageReference Include="Moclawr.MinimalAPI" />
paket add Moclawr.MinimalAPI --version 2.1.3
#r "nuget: Moclawr.MinimalAPI, 2.1.3"
#:package Moclawr.MinimalAPI@2.1.3
#addin nuget:?package=Moclawr.MinimalAPI&version=2.1.3
#tool nuget:?package=Moclawr.MinimalAPI&version=2.1.3
Moclawr.MinimalAPI
Overview
Moclawr.MinimalAPI provides a class-based approach to ASP.NET Core Minimal APIs with automatic endpoint discovery, MediatR integration, and enhanced OpenAPI documentation. It bridges the gap between minimal APIs and traditional controller-based APIs by offering a structured, object-oriented approach while maintaining the performance benefits of minimal APIs.
Key Features
- Class-Based Endpoints: Object-oriented endpoint design with base classes
- Automatic Discovery: Auto-registration of endpoint classes from assemblies
- MediatR Integration: Built-in CQRS pattern support with command/query separation
- Advanced API Versioning: Multiple versioning strategies (URL segment, query string, headers, media type)
- Enhanced OpenAPI Documentation: Rich SwaggerUI with automatic schema generation
- Unique Operation IDs: GUID-based operation IDs prevent duplicate endpoint names
- Intelligent Request Binding: Automatic parameter binding from route, query, body, form, and headers
- Type-Safe Endpoints: Strongly-typed request and response handling
- Flexible Response Types: Support for single items, collections, and custom response wrappers
- Attribute-Based Configuration: Declarative endpoint configuration with attributes
- Custom Authentication: Built-in authorization and authentication support
Latest Updates (v2.1.2)
- ✅ Fixed Duplicate Endpoint Names: Implemented GUID-based unique operation IDs
- ✅ Enhanced SwaggerUI: Improved documentation with versioned endpoints
- ✅ Better Error Handling: Comprehensive error responses and validation
- ✅ Performance Optimizations: Faster endpoint discovery and registration
Installation
Install the package via NuGet Package Manager:
dotnet add package Moclawr.MinimalAPI
Quick Start
1. Register Services
In your Program.cs
:
using MinimalAPI;
var builder = WebApplication.CreateBuilder(args);
// Add MinimalAPI with enhanced documentation and versioning
var versioningOptions = new DefaultVersioningOptions
{
SupportedVersions = [1, 2],
ReadingStrategy = VersionReadingStrategy.UrlSegment | VersionReadingStrategy.Header
};
builder.Services.AddMinimalApiWithSwaggerUI(
title: "My API",
version: "v1",
description: "Comprehensive API built with MinimalAPI framework",
versioningOptions: versioningOptions,
typeof(Program).Assembly
);
var app = builder.Build();
// Auto-discover and map all endpoints
app.MapMinimalEndpoints(versioningOptions, typeof(Program).Assembly);
// Enable documentation
if (app.Environment.IsDevelopment())
{
app.UseMinimalApiDocs();
}
app.Run();
2. Create Your First Endpoint
using MinimalAPI.Endpoints;
using MinimalAPI.Attributes;
using MediatR;
[OpenApiSummary("Get user by ID", "Retrieves a specific user by their unique identifier")]
[ApiVersion(1)]
public class GetUserEndpoint(IMediator mediator)
: SingleEndpointBase<GetUserQuery, UserDto>(mediator)
{
[HttpGet("/api/v1/users/{id}")]
public override async Task<Response<UserDto>> HandleAsync(
GetUserQuery request, CancellationToken ct)
{
return await _mediator.Send(request, ct);
}
}
3. Define Request Models with Smart Binding
using MediatR;
using MinimalAPI.Attributes;
public record GetUserQuery : IRequest<Response<UserDto>>
{
[FromRoute("id")]
public int UserId { get; init; }
[FromQuery]
public bool IncludeDetails { get; init; } = false;
[FromHeader("X-Client-Version")]
public string? ClientVersion { get; init; }
}
public record CreateUserRequest : IRequest<Response<UserDto>>
{
[FromBody]
public string Name { get; init; } = string.Empty;
[FromBody]
public string Email { get; init; } = string.Empty;
[FromQuery]
public bool SendWelcomeEmail { get; init; } = true;
}
Unique Operation IDs
The framework automatically generates unique operation IDs using a combination of readable prefixes and deterministic GUIDs:
Operation ID Format: {FeatureName}_{EndpointName}_{HttpMethod}_{GUID}
Examples:
- Users_GetAll_GET_a1b2c3d4e5f6789012345678901234ab
- Orders_Create_POST_f9e8d7c6b5a4321098765432109876fe
This ensures no duplicate endpoint names across your entire API, even with similar endpoint structures.
Advanced Versioning
Multiple Version Support
[ApiVersion(1)]
public class GetUsersV1Endpoint : CollectionEndpointBase<GetUsersQuery, UserDtoV1>
{
[HttpGet("/api/v1/users")]
public override async Task<ResponseCollection<UserDtoV1>> HandleAsync(...)
{
// Version 1 implementation
}
}
[ApiVersion(2)]
public class GetUsersV2Endpoint : CollectionEndpointBase<GetUsersQueryV2, UserDtoV2>
{
[HttpGet("/api/v2/users")]
public override async Task<ResponseCollection<UserDtoV2>> HandleAsync(...)
{
// Version 2 with enhanced features
}
}
Multiple Reading Strategies
// URL Segment: GET /api/v1/users
// Query Parameter: GET /api/users?version=1
// Header: GET /api/users (with X-API-Version: 1)
// Media Type: GET /api/users (with Accept: application/json;version=1)
Enhanced Documentation Features
Automatic Feature-Based Tagging
Endpoints are automatically grouped by namespace structure:
Namespace: MyApp.Features.Users.Commands → Tag: "Users Commands"
Namespace: MyApp.Features.Orders.Queries → Tag: "Orders Queries"
Rich OpenAPI Attributes
[OpenApiSummary("Create user account", "Creates a new user with validation")]
[OpenApiParameter("name", "User's full name", required: true, example: "John Doe")]
[OpenApiResponse(201, "User created successfully", typeof(UserDto))]
[OpenApiResponse(400, "Invalid user data")]
[ApiVersion(1)]
public class CreateUserEndpoint : SingleEndpointBase<CreateUserCommand, UserDto>
{
[HttpPost("/api/v1/users")]
public override async Task<Response<UserDto>> HandleAsync(...)
{
return await _mediator.Send(request, ct);
}
}
File Upload Support
Single and Multiple Files
public class UploadFilesCommand
{
[FromForm]
public List<IFormFile> Files { get; set; } = [];
[FromForm]
public string Description { get; set; } = string.Empty;
[FromQuery]
public string Folder { get; set; } = "uploads";
}
public class UploadFilesEndpoint(IMediator mediator)
: SingleEndpointBase<UploadFilesCommand, List<FileDto>>(mediator)
{
[HttpPost("/api/v1/files/upload")]
public override async Task<Response<List<FileDto>>> HandleAsync(...)
{
return await _mediator.Send(request, ct);
}
}
Integration Examples
With Entity Framework and Caching
public class GetUsersHandler(
IQueryRepository<User, int> repository,
ICacheService cache,
ILogger<GetUsersHandler> logger)
: IRequestHandler<GetUsersQuery, ResponseCollection<UserDto>>
{
public async Task<ResponseCollection<UserDto>> Handle(
GetUsersQuery request, CancellationToken cancellationToken)
{
var cacheKey = $"users:page:{request.Page}:size:{request.PageSize}";
var cachedUsers = await cache.GetAsync<PagedList<UserDto>>(cacheKey);
if (cachedUsers != null)
{
logger.LogInformation("Retrieved users from cache");
return ResponseHelper.CreateSuccessCollection(cachedUsers);
}
var users = await repository.GetPagedListAsync<UserDto>(
request.Page,
request.PageSize,
filter: u => u.IsActive,
orderBy: q => q.OrderBy(u => u.Name),
cancellationToken: cancellationToken
);
await cache.SetAsync(cacheKey, users, TimeSpan.FromMinutes(15));
return ResponseHelper.CreateSuccessCollection(users);
}
}
Requirements
- .NET 9.0 or higher
- MediatR 12.2.0 or higher
- Microsoft.AspNetCore.OpenApi 9.0.0 or higher
- Swashbuckle.AspNetCore 8.1.2 or higher
Integration with Moclawr Ecosystem
This package works seamlessly with:
- Moclawr.Core: Extension methods and utilities
- Moclawr.Shared: Response models and entity interfaces
- Moclawr.Host: Global exception handling and infrastructure
- Moclawr.EfCore/MongoDb: Repository patterns for data access
- Moclawr.Services.Caching: Response caching for API endpoints
- Moclawr.Services.External: External service integration
- Moclawr.Services.Autofac: Enhanced dependency injection
License
This package is licensed under the MIT License.
Note: Version 2.1.2 introduces GUID-based operation IDs that solve the "Duplicate endpoint name" issue definitively. All endpoints now have globally unique identifiers while maintaining human-readable prefixes for better developer experience.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- MediatR (>= 12.2.0)
- Microsoft.AspNetCore.OpenApi (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.5)
- Moclawr.Core (>= 2.1.0)
- Moclawr.Shared (>= 2.0.1)
- Swashbuckle.AspNetCore.SwaggerGen (>= 8.1.2)
- Swashbuckle.AspNetCore.SwaggerUI (>= 8.1.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
2.1.9 | 281 | 6/4/2025 |
2.1.8 | 141 | 6/4/2025 |
2.1.7 | 147 | 6/4/2025 |
2.1.6 | 148 | 6/4/2025 |
2.1.4 | 118 | 5/30/2025 |
2.1.3 | 137 | 5/30/2025 |
2.1.2 | 129 | 5/30/2025 |
2.1.1 | 142 | 5/28/2025 |
2.1.0 | 141 | 5/28/2025 |
2.0.1 | 65 | 5/24/2025 |
2.0.0 | 72 | 5/24/2025 |
1.0.3 | 68 | 5/24/2025 |
1.0.2.1 | 78 | 5/24/2025 |
1.0.2 | 145 | 5/22/2025 |
1.0.1 | 148 | 5/21/2025 |
1.0.0 | 148 | 5/19/2025 |
Added SwaggerUI support for enhanced API documentation experience.