{"id":17758321,"url":"https://github.com/marcominerva/MinimalHelpers","last_synced_at":"2025-03-15T08:31:56.656Z","repository":{"id":40304721,"uuid":"436230296","full_name":"marcominerva/MinimalHelpers","owner":"marcominerva","description":"A collection of helpers libraries for Minimal API projects.","archived":false,"fork":false,"pushed_at":"2025-01-15T14:20:14.000Z","size":191,"stargazers_count":115,"open_issues_count":1,"forks_count":4,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-02-04T09:09:55.697Z","etag":null,"topics":["aspnetcore","csharp","hacktoberfest","minimal-api","minimalapi","minimalapis","net","openapi","routing","swagger","visual-studio"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcominerva.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-08T11:56:39.000Z","updated_at":"2025-02-04T06:50:02.000Z","dependencies_parsed_at":"2024-02-27T09:41:06.933Z","dependency_job_id":"fb96c607-9310-4de1-84e0-8a19e3eb0166","html_url":"https://github.com/marcominerva/MinimalHelpers","commit_stats":{"total_commits":43,"total_committers":3,"mean_commits":"14.333333333333334","dds":0.06976744186046513,"last_synced_commit":"5a902a93360f4ff33e4be1d6ce6488c4143db707"},"previous_names":["marcominerva/minimalhelpers.registration"],"tags_count":45,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcominerva%2FMinimalHelpers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcominerva%2FMinimalHelpers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcominerva%2FMinimalHelpers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcominerva%2FMinimalHelpers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcominerva","download_url":"https://codeload.github.com/marcominerva/MinimalHelpers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243707282,"owners_count":20334613,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnetcore","csharp","hacktoberfest","minimal-api","minimalapi","minimalapis","net","openapi","routing","swagger","visual-studio"],"created_at":"2024-10-26T18:01:34.915Z","updated_at":"2025-03-15T08:31:56.551Z","avatar_url":"https://github.com/marcominerva.png","language":"C#","funding_links":[],"categories":["hacktoberfest","csharp","Content"],"sub_categories":["162. [MinimalHelpers.Routing.Analyzers](https://ignatandrei.github.io/RSCG_Examples/v2/docs/MinimalHelpers.Routing.Analyzers) , in the [API](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#api) category"],"readme":"# Minimal APIs Helpers\n\n[![Lint Code Base](https://github.com/marcominerva/MinimalHelpers/actions/workflows/linter.yml/badge.svg)](https://github.com/marcominerva/MinimalHelpers/actions/workflows/linter.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/marcominerva/MinimalHelpers/blob/master/LICENSE)\n\nA collection of helpers libraries for Minimal API projects.\n\n## MinimalHelpers.Routing\n\n[![Nuget](https://img.shields.io/nuget/v/MinimalHelpers.Routing)](https://www.nuget.org/packages/MinimalHelpers.Routing)\n[![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.Routing)](https://www.nuget.org/packages/MinimalHelpers.Routing)\n\nA library that provides Routing helpers for Minimal API projects for automatic endpoints registration using Reflection.\n\n### Installation\n\nThe 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**:\n\n```shell\ndotnet add package MinimalHelpers.Routing\n```\n\n### Usage\n\nCreate a class to hold your route handlers registration and make it implementing the `IEndpointRouteHandlerBuilder` interface:\n\n```csharp\npublic class PeopleEndpoints : MinimalHelpers.Routing.IEndpointRouteHandlerBuilder\n{\n    public static void MapEndpoints(IEndpointRouteBuilder endpoints)\n    {\n        endpoints.MapGet(\"/api/people\", GetList);\n        endpoints.MapGet(\"/api/people/{id:guid}\", Get);\n        endpoints.MapPost(\"/api/people\", Insert);\n        endpoints.MapPut(\"/api/people/{id:guid}\", Update);\n        endpoints.MapDelete(\"/api/people/{id:guid}\", Delete);\n    }\n\n    // ...\n}\n```\n\nCall the `MapEndpoints()` extension method on the **WebApplication** object inside *Program.cs* before the `Run()` method invocation:\n\n```csharp\n// using MinimalHelpers.Routing;\napp.MapEndpoints();\n\napp.Run();\n```\n\nBy 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:\n\n- Use the `MapEndpoints()` overload that takes the Assembly to scan as argument\n- Use the `MapEndpointsFromAssemblyContaining\u003cT\u003e()` extension method and specify a type that is contained in the Assembly you want to scan\n\nYou 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:\n\n```csharp\napp.MapEndpoints(type =\u003e\n{\n    if (type.Name.StartsWith(\"Products\"))\n    {\n        return false;\n    }\n\n    return true;\n});\n```\n\n\u003e **Note**\nThese 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.\n\n## MinimalHelpers.Routing.Analyzers\n\n[![Nuget](https://img.shields.io/nuget/v/MinimalHelpers.Routing.Analyzers)](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers)\n[![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.Routing.Analyzers)](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers)\n\nA library that provides a Source Generator for automatic endpoints registration in Minimal API projects.\n\n### Installation\n\nThe 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**:\n\n```shell\ndotnet add package MinimalHelpers.Routing.Analyzers\n```\n\n### Usage\n\nCreate a class to hold your route handlers registration and make it implementing the `IEndpointRouteHandlerBuilder` interface:\n\n```csharp\npublic class PeopleEndpoints : IEndpointRouteHandlerBuilder\n{\n    public static void MapEndpoints(IEndpointRouteBuilder endpoints)\n    {\n        endpoints.MapGet(\"/api/people\", GetList);\n        endpoints.MapGet(\"/api/people/{id:guid}\", Get);\n        endpoints.MapPost(\"/api/people\", Insert);\n        endpoints.MapPut(\"/api/people/{id:guid}\", Update);\n        endpoints.MapDelete(\"/api/people/{id:guid}\", Delete);\n    }\n\n    // ...\n}\n```\n\n\u003e **Note**\nYou only need to use the **MinimalHelpers.Routing.Analyzers** package. With this Source Generator, the `IEndpointRouteHandlerBuilder` interface is auto-generated.\n\nCall the `MapEndpoints()` extension method on the **WebApplication** object inside *Program.cs* before the `Run()` method invocation:\n\n```csharp\napp.MapEndpoints();\n\napp.Run();\n```\n\n\u003e **Note**\nThe `MapEndpoints` method is generated by the Source Generator.\n\n## MinimalHelpers.OpenApi\n\n[![Nuget](https://img.shields.io/nuget/v/MinimalHelpers.OpenApi)](https://www.nuget.org/packages/MinimalHelpers.OpenApi)\n[![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.OpenApi)](https://www.nuget.org/packages/MinimalHelpers.OpenApi)\n\nA library that provides OpenApi helpers for Minimal API projects.\n\n### Installation\n\nThe 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**:\n\n```shell\ndotnet add package MinimalHelpers.OpenApi\n```\n\n### Usage\n\n***Extension methods for OpenApi***\n\nThis 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:\n\n```csharp\nendpoints.MapPost(\"login\", LoginAsync)\n    .AllowAnonymous()\n    .WithValidation\u003cLoginRequest\u003e()\n    .Produces\u003cLoginResponse\u003e(StatusCodes.Status200OK)\n    .Produces\u003cLoginResponse\u003e(StatusCodes.Status206PartialContent)\n    .Produces(StatusCodes.Status403Forbidden)\n    .ProducesValidationProblem()\n    .WithOpenApi(operation =\u003e\n    {\n        operation.Summary = \"Performs the login of a user\";\n\n        operation.Response(StatusCodes.Status200OK).Description = \"Login successful\";\n        operation.Response(StatusCodes.Status206PartialContent).Description = \"The user is logged in, but the password has expired and must be changed\";\n        operation.Response(StatusCodes.Status400BadRequest).Description = \"Incorrect username and/or password\";\n        operation.Response(StatusCodes.Status403Forbidden).Description = \"The user was blocked due to too many failed logins\";\n\n        return operation;\n    });\n ```\n\n ***Extension methods for RouteHandlerBuilder***\n\n Often we have endpoints with multiple 4xx return values, each of which produces a `ProblemDetails` response:\n\n ```csharp\n endpoints.MapGet(\"/api/people/{id:guid}\", Get)\n    .ProducesProblem(StatusCodes.Status400BadRequest)\n    .ProducesProblem(StatusCodes.Status401Unauthorized)\n    .ProducesProblem(StatusCodes.Status403Forbidden)\n    .ProducesProblem(StatusCodes.Status404NotFound);\n ```\n\n To avoid multiple calls to `ProducesProblem`, we can use the `ProducesDefaultProblem` extension method provided by the library:\n\n ```csharp\nendpoints.MapGet(\"/api/people/{id:guid}\", Get)\n    .ProducesDefaultProblem(StatusCodes.Status400BadRequest, StatusCodes.Status401Unauthorized,\n        StatusCodes.Status403Forbidden, StatusCodes.Status404NotFound);\n ```\n\n## MinimalHelpers.Validation\n\n[![Nuget](https://img.shields.io/nuget/v/MinimalHelpers.Validation)](https://www.nuget.org/packages/MinimalHelpers.Validation)\n[![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.Validation)](https://www.nuget.org/packages/MinimalHelpers.Validation)\n\nA library that provides an Endpoint filter for Minimal API projects to perform validation with Data Annotations, using the \u003ca href=\"https://github.com/DamianEdwards/MiniValidation\"\u003eMiniValidation\u003c/a\u003e library.\n\n### Installation\n\nThe 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**:\n\n```shell\ndotnet add package MinimalHelpers.Validation\n```\n\n### Usage\n\nDecorates a class with attributes to define the validation rules:\n\n```csharp\nusing System.ComponentModel.DataAnnotations;\n\npublic class Person\n{\n    [Required]\n    [MaxLength(20)]\n    public string? FirstName { get; set; }\n\n    [Required]\n    [MaxLength(20)]\n    public string? LastName { get; set; }\n\n    [MaxLength(50)]\n    public string? City { get; set; }\n}\n```\n\nAdd the `WithValidation\u003cT\u003e()` extension method to enable the validation filter:\n\n```csharp\nusing MinimalHelpers.Validation;\n\napp.MapPost(\"/api/people\", (Person person) =\u003e\n    {\n        // ...\n    })\n    .WithValidation\u003cPerson\u003e();\n```\n\nIf the validation fails, the response will be a `400 Bad Request` with a `ValidationProblemDetails` object containing the validation errors, for example:\n\n```json\n{\n  \"type\": \"https://tools.ietf.org/html/rfc9110#section-15.5.1\",\n  \"title\": \"One or more validation errors occurred\",\n  \"status\": 400,\n  \"instance\": \"/api/people\",\n  \"traceId\": \"00-009c0162ba678cae2ee391815dbbb59d-0a3a5b0c16d053e6-00\",\n  \"errors\": {\n    \"FirstName\": [\n      \"The field FirstName must be a string or array type with a maximum length of '20'.\"\n    ],\n    \"LastName\": [\n      \"The LastName field is required.\"\n    ]\n  }\n}\n```\n\nIf you want to customize validation, you can use the `ConfigureValidation` extension method:\n\n```csharp\nusing MinimalHelpers.Validation;\n\nbuilder.Services.ConfigureValidation(options =\u003e\n{\n    // If you want to get errors as a list instead of a dictionary.\n    options.ErrorResponseFormat = ErrorResponseFormat.List;\n\n    // The default is \"One or more validation errors occurred\"\n    options.ValidationErrorTitleMessageFactory =\n        (context, errors) =\u003e $\"There was {errors.Values.Sum(v =\u003e v.Length)} error(s)\";\n});\n```\n\nYou can use the `ValidationErrorTitleMessageFactory`, for example, if you want to localized the `title` property of the response using a RESX file.\n\n## MinimalHelpers.FluentValidation\n\n[![Nuget](https://img.shields.io/nuget/v/MinimalHelpers.FluentValidation)](https://www.nuget.org/packages/MinimalHelpers.FluentValidation)\n[![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.FluentValidation)](https://www.nuget.org/packages/MinimalHelpers.FluentValidation)\n\nA library that provides an Endpoint filter for Minimal API projects to perform validation using \u003ca href=\"https://fluentvalidation.net\"\u003eFluentValidation\u003c/a\u003e.\n\n### Installation\n\nThe 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**:\n\n```shell\ndotnet add package MinimalHelpers.FluentValidation\n```\n\n### Usage\n\nCreate a class that extends AbstractValidator\u003cT\u003e and define the validation rules:\n\n```csharp\nusing FluentValidation;\n\npublic record class Product(string Name, string Description, double UnitPrice);\n\npublic class ProductValidator : AbstractValidator\u003cProduct\u003e\n{\n    public ProductValidator()\n    {\n        RuleFor(p =\u003e p.Name).NotEmpty().MaximumLength(50).EmailAddress();\n        RuleFor(p =\u003e p.Description).MaximumLength(500);\n        RuleFor(p =\u003e p.UnitPrice).GreaterThan(0);\n    }\n}\n```\n\nRegister validators in the Service Collection:\n\n```csharp\nusing FluentValidation;\n\n// Assuming the validators are in the same assembly as the Program class\nbuilder.Services.AddValidatorsFromAssemblyContaining\u003cProgram\u003e();\n\n```\n\nAdd the `WithValidation\u003cT\u003e()` extension method to enable the validation filter:\n\n```csharp\nusing MinimalHelpers.FluentValidation;\n\napp.MapPost(\"/api/products\", (Product product) =\u003e\n    {\n        // ...\n    })\n    .WithValidation\u003cProduct\u003e();\n```\n\nIf the validation fails, the response will be a `400 Bad Request` with a `ValidationProblemDetails` object containing the validation errors, for example:\n\n```json\n{\n  \"type\": \"https://tools.ietf.org/html/rfc9110#section-15.5.1\",\n  \"title\": \"One or more validation errors occurred\",\n  \"status\": 400,\n  \"instance\": \"/api/products\",\n  \"traceId\": \"00-f4ced0ae470424dd04cbcebe5f232dc5-bbdcc59f310ebfb8-00\",\n  \"errors\": {\n    \"Name\": [\n      \"'Name' cannot be empty.\"\n    ],\n    \"UnitPrice\": [\n      \"'Unit Price' must be grater than '0'.\"\n    ]\n  }\n}\n```\n\nIf you want to customize validation, you can use the `ConfigureValidation` extension method:\n\n```csharp\nusing MinimalHelpers.Validation;\n\nbuilder.Services.ConfigureValidation(options =\u003e\n{\n    // If you want to get errors as a list instead of a dictionary.\n    options.ErrorResponseFormat = ErrorResponseFormat.List;\n\n    // The default is \"One or more validation errors occurred\"\n    options.ValidationErrorTitleMessageFactory =\n        (context, errors) =\u003e $\"There was {errors.Values.Sum(v =\u003e v.Length)} error(s)\";\n});\n```\n\nYou can use the `ValidationErrorTitleMessageFactory`, for example, if you want to localized the `title` property of the response using a RESX file.\n\n\n**Contribute**\n\nThe 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. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcominerva%2FMinimalHelpers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcominerva%2FMinimalHelpers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcominerva%2FMinimalHelpers/lists"}