MinApiLib.Endpoints
9.0.0
dotnet add package MinApiLib.Endpoints --version 9.0.0
NuGet\Install-Package MinApiLib.Endpoints -Version 9.0.0
<PackageReference Include="MinApiLib.Endpoints" Version="9.0.0" />
paket add MinApiLib.Endpoints --version 9.0.0
#r "nuget: MinApiLib.Endpoints, 9.0.0"
// Install MinApiLib.Endpoints as a Cake Addin #addin nuget:?package=MinApiLib.Endpoints&version=9.0.0 // Install MinApiLib.Endpoints as a Cake Tool #tool nuget:?package=MinApiLib.Endpoints&version=9.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:
Get
Post
Put
Delete
Patch
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. |
-
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.