https://github.com/marcominerva/MinimalHelpers
A collection of helpers libraries for Minimal API projects.
https://github.com/marcominerva/MinimalHelpers
aspnetcore csharp hacktoberfest minimal-api minimalapi minimalapis net openapi routing swagger visual-studio
Last synced: about 1 month ago
JSON representation
A collection of helpers libraries for Minimal API projects.
- Host: GitHub
- URL: https://github.com/marcominerva/MinimalHelpers
- Owner: marcominerva
- License: mit
- Created: 2021-12-08T11:56:39.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2025-01-15T14:20:14.000Z (3 months ago)
- Last Synced: 2025-02-04T09:09:55.697Z (2 months ago)
- Topics: aspnetcore, csharp, hacktoberfest, minimal-api, minimalapi, minimalapis, net, openapi, routing, swagger, visual-studio
- Language: C#
- Homepage:
- Size: 187 KB
- Stars: 115
- Watchers: 7
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- RSCG_Examples - https://github.com/marcominerva/MinimalHelpers
README
# Minimal APIs Helpers
[](https://github.com/marcominerva/MinimalHelpers/actions/workflows/linter.yml)
[](https://github.com/marcominerva/MinimalHelpers/blob/master/LICENSE)A collection of helpers libraries for Minimal API projects.
## MinimalHelpers.Routing
[](https://www.nuget.org/packages/MinimalHelpers.Routing)
[](https://www.nuget.org/packages/MinimalHelpers.Routing)A library that provides Routing helpers for Minimal API projects for automatic endpoints registration using Reflection.
### Installation
The library is available on [NuGet](https://www.nuget.org/packages/MinimalHelpers.Routing). Just search for *MinimalHelpers.Routing* in the **Package Manager GUI** or run the following command in the **.NET CLI**:
```shell
dotnet add package MinimalHelpers.Routing
```### Usage
Create a class to hold your route handlers registration and make it implementing the `IEndpointRouteHandlerBuilder` interface:
```csharp
public class PeopleEndpoints : MinimalHelpers.Routing.IEndpointRouteHandlerBuilder
{
public static void MapEndpoints(IEndpointRouteBuilder endpoints)
{
endpoints.MapGet("/api/people", GetList);
endpoints.MapGet("/api/people/{id:guid}", Get);
endpoints.MapPost("/api/people", Insert);
endpoints.MapPut("/api/people/{id:guid}", Update);
endpoints.MapDelete("/api/people/{id:guid}", Delete);
}// ...
}
```Call the `MapEndpoints()` extension method on the **WebApplication** object inside *Program.cs* before the `Run()` method invocation:
```csharp
// using MinimalHelpers.Routing;
app.MapEndpoints();app.Run();
```By default, `MapEndpoints()` will scan the calling Assembly to search for classes that implement the `IEndpointRouteHandlerBuilder` interface. If your route handlers are defined in another Assembly, you have two alternatives:
- Use the `MapEndpoints()` overload that takes the Assembly to scan as argument
- Use the `MapEndpointsFromAssemblyContaining()` extension method and specify a type that is contained in the Assembly you want to scanYou can also explicitly decide what types (among the ones that implement the `IRouteEndpointHandlerBuilder` interface) you want to actually map, passing a predicate to the `MapEndpoints` method:
```csharp
app.MapEndpoints(type =>
{
if (type.Name.StartsWith("Products"))
{
return false;
}return true;
});
```> **Note**
These methods rely on Reflection to scan the Assembly and find the classes that implement the `IEndpointRouteHandlerBuilder` interface. This can have a performance impact, especially in large projects. If you have performance issues, consider using the explicit registration method. Moreover, this solution is incompatibile with Native AOT.## MinimalHelpers.Routing.Analyzers
[](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers)
[](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers)A library that provides a Source Generator for automatic endpoints registration in Minimal API projects.
### Installation
The library is available on [NuGet](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers). Just search for *MinimalHelpers.Routing* in the **Package Manager GUI** or run the following command in the **.NET CLI**:
```shell
dotnet add package MinimalHelpers.Routing.Analyzers
```### Usage
Create a class to hold your route handlers registration and make it implementing the `IEndpointRouteHandlerBuilder` interface:
```csharp
public class PeopleEndpoints : IEndpointRouteHandlerBuilder
{
public static void MapEndpoints(IEndpointRouteBuilder endpoints)
{
endpoints.MapGet("/api/people", GetList);
endpoints.MapGet("/api/people/{id:guid}", Get);
endpoints.MapPost("/api/people", Insert);
endpoints.MapPut("/api/people/{id:guid}", Update);
endpoints.MapDelete("/api/people/{id:guid}", Delete);
}// ...
}
```> **Note**
You only need to use the **MinimalHelpers.Routing.Analyzers** package. With this Source Generator, the `IEndpointRouteHandlerBuilder` interface is auto-generated.Call the `MapEndpoints()` extension method on the **WebApplication** object inside *Program.cs* before the `Run()` method invocation:
```csharp
app.MapEndpoints();app.Run();
```> **Note**
The `MapEndpoints` method is generated by the Source Generator.## MinimalHelpers.OpenApi
[](https://www.nuget.org/packages/MinimalHelpers.OpenApi)
[](https://www.nuget.org/packages/MinimalHelpers.OpenApi)A library that provides OpenApi helpers for Minimal API projects.
### Installation
The library is available on [NuGet](https://www.nuget.org/packages/MinimalHelpers.OpenApi). Just search for *MinimalHelpers.OpenApi* in the **Package Manager GUI** or run the following command in the **.NET CLI**:
```shell
dotnet add package MinimalHelpers.OpenApi
```### Usage
***Extension methods for OpenApi***
This library provides some extensions methods that simplify the OpenAPI configuration in Minimal API projects. For example, it is possible to customize the description of a response using its status code:
```csharp
endpoints.MapPost("login", LoginAsync)
.AllowAnonymous()
.WithValidation()
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status206PartialContent)
.Produces(StatusCodes.Status403Forbidden)
.ProducesValidationProblem()
.WithOpenApi(operation =>
{
operation.Summary = "Performs the login of a user";operation.Response(StatusCodes.Status200OK).Description = "Login successful";
operation.Response(StatusCodes.Status206PartialContent).Description = "The user is logged in, but the password has expired and must be changed";
operation.Response(StatusCodes.Status400BadRequest).Description = "Incorrect username and/or password";
operation.Response(StatusCodes.Status403Forbidden).Description = "The user was blocked due to too many failed logins";return operation;
});
```***Extension methods for RouteHandlerBuilder***
Often we have endpoints with multiple 4xx return values, each of which produces a `ProblemDetails` response:
```csharp
endpoints.MapGet("/api/people/{id:guid}", Get)
.ProducesProblem(StatusCodes.Status400BadRequest)
.ProducesProblem(StatusCodes.Status401Unauthorized)
.ProducesProblem(StatusCodes.Status403Forbidden)
.ProducesProblem(StatusCodes.Status404NotFound);
```To avoid multiple calls to `ProducesProblem`, we can use the `ProducesDefaultProblem` extension method provided by the library:
```csharp
endpoints.MapGet("/api/people/{id:guid}", Get)
.ProducesDefaultProblem(StatusCodes.Status400BadRequest, StatusCodes.Status401Unauthorized,
StatusCodes.Status403Forbidden, StatusCodes.Status404NotFound);
```## MinimalHelpers.Validation
[](https://www.nuget.org/packages/MinimalHelpers.Validation)
[](https://www.nuget.org/packages/MinimalHelpers.Validation)A library that provides an Endpoint filter for Minimal API projects to perform validation with Data Annotations, using the MiniValidation library.
### Installation
The library is available on [NuGet](https://www.nuget.org/packages/MinimalHelpers.Validation). Just search for *MinimalHelpers.Validation* in the **Package Manager GUI** or run the following command in the **.NET CLI**:
```shell
dotnet add package MinimalHelpers.Validation
```### Usage
Decorates a class with attributes to define the validation rules:
```csharp
using System.ComponentModel.DataAnnotations;public class Person
{
[Required]
[MaxLength(20)]
public string? FirstName { get; set; }[Required]
[MaxLength(20)]
public string? LastName { get; set; }[MaxLength(50)]
public string? City { get; set; }
}
```Add the `WithValidation()` extension method to enable the validation filter:
```csharp
using MinimalHelpers.Validation;app.MapPost("/api/people", (Person person) =>
{
// ...
})
.WithValidation();
```If the validation fails, the response will be a `400 Bad Request` with a `ValidationProblemDetails` object containing the validation errors, for example:
```json
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred",
"status": 400,
"instance": "/api/people",
"traceId": "00-009c0162ba678cae2ee391815dbbb59d-0a3a5b0c16d053e6-00",
"errors": {
"FirstName": [
"The field FirstName must be a string or array type with a maximum length of '20'."
],
"LastName": [
"The LastName field is required."
]
}
}
```If you want to customize validation, you can use the `ConfigureValidation` extension method:
```csharp
using MinimalHelpers.Validation;builder.Services.ConfigureValidation(options =>
{
// If you want to get errors as a list instead of a dictionary.
options.ErrorResponseFormat = ErrorResponseFormat.List;// The default is "One or more validation errors occurred"
options.ValidationErrorTitleMessageFactory =
(context, errors) => $"There was {errors.Values.Sum(v => v.Length)} error(s)";
});
```You can use the `ValidationErrorTitleMessageFactory`, for example, if you want to localized the `title` property of the response using a RESX file.
## MinimalHelpers.FluentValidation
[](https://www.nuget.org/packages/MinimalHelpers.FluentValidation)
[](https://www.nuget.org/packages/MinimalHelpers.FluentValidation)A library that provides an Endpoint filter for Minimal API projects to perform validation using FluentValidation.
### Installation
The library is available on [NuGet](https://www.nuget.org/packages/MinimalHelpers.FluentValidation). Just search for *MinimalHelpers.FluentValidation* in the **Package Manager GUI** or run the following command in the **.NET CLI**:
```shell
dotnet add package MinimalHelpers.FluentValidation
```### Usage
Create a class that extends AbstractValidator and define the validation rules:
```csharp
using FluentValidation;public record class Product(string Name, string Description, double UnitPrice);
public class ProductValidator : AbstractValidator
{
public ProductValidator()
{
RuleFor(p => p.Name).NotEmpty().MaximumLength(50).EmailAddress();
RuleFor(p => p.Description).MaximumLength(500);
RuleFor(p => p.UnitPrice).GreaterThan(0);
}
}
```Register validators in the Service Collection:
```csharp
using FluentValidation;// Assuming the validators are in the same assembly as the Program class
builder.Services.AddValidatorsFromAssemblyContaining();```
Add the `WithValidation()` extension method to enable the validation filter:
```csharp
using MinimalHelpers.FluentValidation;app.MapPost("/api/products", (Product product) =>
{
// ...
})
.WithValidation();
```If the validation fails, the response will be a `400 Bad Request` with a `ValidationProblemDetails` object containing the validation errors, for example:
```json
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred",
"status": 400,
"instance": "/api/products",
"traceId": "00-f4ced0ae470424dd04cbcebe5f232dc5-bbdcc59f310ebfb8-00",
"errors": {
"Name": [
"'Name' cannot be empty."
],
"UnitPrice": [
"'Unit Price' must be grater than '0'."
]
}
}
```If you want to customize validation, you can use the `ConfigureValidation` extension method:
```csharp
using MinimalHelpers.Validation;builder.Services.ConfigureValidation(options =>
{
// If you want to get errors as a list instead of a dictionary.
options.ErrorResponseFormat = ErrorResponseFormat.List;// The default is "One or more validation errors occurred"
options.ValidationErrorTitleMessageFactory =
(context, errors) => $"There was {errors.Values.Sum(v => v.Length)} error(s)";
});
```You can use the `ValidationErrorTitleMessageFactory`, for example, if you want to localized the `title` property of the response using a RESX file.
**Contribute**
The project is constantly evolving. Contributions are welcome. Feel free to file issues and pull requests on the repo and we'll address them as we can.