MinApiLib.Endpoints
10.0.0
dotnet add package MinApiLib.Endpoints --version 10.0.0
NuGet\Install-Package MinApiLib.Endpoints -Version 10.0.0
<PackageReference Include="MinApiLib.Endpoints" Version="10.0.0" />
<PackageVersion Include="MinApiLib.Endpoints" Version="10.0.0" />
<PackageReference Include="MinApiLib.Endpoints" />
paket add MinApiLib.Endpoints --version 10.0.0
#r "nuget: MinApiLib.Endpoints, 10.0.0"
#:package MinApiLib.Endpoints@10.0.0
#addin nuget:?package=MinApiLib.Endpoints&version=10.0.0
#tool nuget:?package=MinApiLib.Endpoints&version=10.0.0
MinApiLib.Endpoints
This package provides extensions that enable creating endpoints using records and one file per endpoint.
Table of conents:
Installation
You can install this package using either the NuGet package manager or the .NET CLI:
Using the NuGet package manager:
Install-Package MinApiLib.Endpoints
Using the .NET CLI:
dotnet add package MinApiLib.Endpoints
Usage
To create endpoints, you can use the MapEndpoints extension method to map all endpoints in the assembly.
global using MinApiLib.Endpoints;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapEndpoints();
app.Run();
By default, the method maps the classes in the current executing assembly, but you can change this behavior by adding the Assembly parameter.:
app.MapEndpoints(typeof(SomeObject).Assembly);
Then, you can create endpoints:
public record Hello() : Get("/hello")
{
public IResult Handle()
=> Results.Ok("Hello World!");
}
And test it with curl:
$ curl "http://localhost:5000/hello"
"Hello World!"%
Endpoints
Naming convention endpoints
If you want to use the naming convention to create endpoints, you can use the following records:
GetPostPutDeletePatch
This endpoints are based on the Endpoint class, which provides the following methods:
Configure: this virtual method is called when the endpoint is configured. You can override it to add your custom configuration.
These endpoints will look for a method named Handle or HandleAsync in the record to use it as the endpoint handler.
public record Hello(): Get("/hello")
{
public IResult Handle()
=> Results.Ok("Hello World!");
}
or:
public record Hello(): Get("/hello")
{
public Task<IResult> HandleAsync()
=> Task.FromResult(Results.Ok("Hello World!"));
}
You can specify the parameters and bind them in the same way you do in the minimal API mapping methods:
public record Hello(): Get("/hello/{name}")
{
public IResult Handle(string name)
=> Results.Ok($"Hello {name}!");
}
This is the same as:
public record Hello(): Get("/hello/{name}")
{
public IResult Handle([FromRoute] string name)
=> Results.Ok($"Hello {name}!");
}
You can use all attribute decorators to specify the Handle method parameters:
public record Hello(): Get("/hello")
{
public IResult Handle([FromQuery] string name, [FromHeader] string userAgent, [FromServices] CancellationToken cancellationToken)
=> Results.Ok($"Hello {name}! Your user agent is {userAgent}.");
}
And you can also specify the response type:
public record struct Response(string Message);
public record Hello(): Get("/hello/{name}")
{
public Response Handle(string name)
=> new Response($"Hello {name}!");
}
Synchronous handlers
For synchronous strong typed handlers, you can use the following records:
GetHandler,GetHandler<TRequest>andGetHandler<TRequest, TResponse>PostHandler,PostHandler<TRequest>andPostHandler<TRequest, TResponse>PutHandler,PutHandler<TRequest>andPutHandler<TRequest, TResponse>DeleteHandler,DeleteHandler<TRequest>andDeleteHandler<TRequest, TResponse>PatchHandler,PatchHandler<TRequest>andPatchHandler<TRequest, TResponse>
These endpoints are based on the EndpointHandler class, which provides the following methods:
Configure: this virtual method is called when the endpoint is configured. You can override it to add your custom configuration.Handle: this abstract method is called when the endpoint is invoked. You must override it to implement your custom logic.
public record Hello() : GetHandler("/hello")
{
protected override RouteHandlerBuilder Configure(RouteHandlerBuilder builder)
=> builder
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status204NoContent)
.WithName("Hello")
.WithTags("hello", "world");
protected override IResult Handle()
=> Results.Ok("Hello World!");
}
If you specify the TRequest generic type, the endpoint will automatically bind the request to the specified type using AsParametersAttribute.
public record struct Request(string Name);
public record Hello() : GetHandler<Request>("/hello/{name}")
{
protected override IResult Handle(Request request)
=> Results.Ok($"Hello {request.Name}!");
}
This is the same as:
public record struct Request([FromRoute] string Name);
public record Hello() : GetHandler<Request>("/hello/{name}")
{
protected override IResult Handle(Request request)
=> Results.Ok($"Hello {request.Name}!");
}
In the Request record you can specify the parameter name using the FromRouteAttribute, FromQueryAttribute, FromHeaderAttribute, FromBodyAttribute or FromServicesAttribute attributes.
And if you specify the TResponse generic type, the endpoint will automatically return the response to the specified type.
public record struct Request(string Name);
public record struct Response(string Message);
public record Hello() : GetHandler<Request, Response>("/hello/{name}")
{
protected override Response Handle(Request request)
=> new Response($"Hello {request.Name}!");
}
Asynchronous handlers
For asynchronous strong typed handlers, you can use the following records:
GetHandlerAsync,GetHandlerAsync<TRequest>andGetHandlerAsync<TRequest, TResponse>PostHandlerAsync,PostHandlerAsync<TRequest>andPostHandlerAsync<TRequest, TResponse>PutHandlerAsync,PutHandlerAsync<TRequest>andPutHandlerAsync<TRequest, TResponse>DeleteHandlerAsync,DeleteHandlerAsync<TRequest>andDeleteHandlerAsync<TRequest, TResponse>PatchHandlerAsync,PatchHandlerAsync<TRequest>andPatchHandlerAsync<TRequest, TResponse>
These endpoints are based on the EndpointHandlerAsync class, which provides the following methods:
Configure: this virtual method is called when the endpoint is configured. You can override it to add your custom configuration.HandleAsync: this abstract method is called when the endpoint is invoked. You must override it to implement your custom logic.
public record Hello() : GetHandlerAsync("/hello")
{
protected override RouteHandlerBuilder Configure(RouteHandlerBuilder builder)
=> builder
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status204NoContent)
.WithName("Hello")
.WithTags("hello", "world");
protected override async Task<IResult> HandleAsync(CancellationToken cancellationToken)
{
await Task.Delay(1000);
return Results.Ok("Hello World!");
}
}
If you specify the TRequest generic type, the endpoint will automatically bind the request to the specified type using AsParametersAttribute.
public record struct Request(string Name);
public record Hello() : GetHandlerAsync<Request>("/hello/{name}")
{
protected override async Task<IResult> HandleAsync(Request request, CancellationToken cancellationToken)
{
await Task.Delay(1000);
return Results.Ok($"Hello {request.Name}!");
}
}
This is the same as:
public record struct Request([FromRoute] string Name);
public record Hello() : GetHandlerAsync<Request>("/hello/{name}")
{
protected override async Task<IResult> HandleAsync(Request request, CancellationToken cancellationToken)
{
await Task.Delay(1000);
return Results.Ok($"Hello {request.Name}!");
}
}
In the Request record you can specify the parameter name using the FromRouteAttribute, FromQueryAttribute, FromHeaderAttribute, FromBodyAttribute or FromServicesAttribute attributes.
And if you specify the TResponse generic type, the endpoint will automatically return the response to the specified type.
public record struct Request(string Name);
public record struct Response(string Message);
public record Hello() : GetHandlerAsync<Request, Response>("/hello/{name}")
{
protected override async Task<Response> HandleAsync(Request request, CancellationToken cancellationToken)
{
await Task.Delay(1000);
return new Response($"Hello {request.Name}!");
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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 is compatible. 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. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.