Skip to content

Filters

IEndpointFilter is an interface provided by ASP.NET Core Minimal APIs. It lets you run logic before and after a request reaches the handler.

Middleware is applied globally to all requests, while filters can be scoped to specific endpoints or groups. This lets you apply cross-cutting concerns such as audit logging, validation, or rate limiting only where they are needed.

In AxisEndpoints, register filters with config.AddFilter<TFilter>(). Filters are resolved from the DI container, so constructor injection works as expected.

Filter classes defined in the assembly or assemblies passed to AddAxisEndpoints() — by default, the entry assembly — are registered automatically by its scanning, so manual registration is not required for those. This does not extend to filters shipped in a separate NuGet package, since that package’s assembly is not scanned unless you pass it explicitly. Such packages must register their filters themselves; the CSV Helper extension does this via AddAxisEndpointsCsvHelper(). See the CSV Helper extension for an example.


Implement IEndpointFilter and register it with config.AddFilter<TFilter>(). Filters are resolved from DI per request, so constructor injection is supported. Registering a filter on a group applies it to all endpoints in that group.

public class LoggingFilter : IEndpointFilter
{
private readonly ILogger<LoggingFilter> _logger;
public LoggingFilter(ILogger<LoggingFilter> logger) => _logger = logger;
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext context,
EndpointFilterDelegate next)
{
_logger.LogInformation("{Method} {Path}",
context.HttpContext.Request.Method,
context.HttpContext.Request.Path);
var result = await next(context);
_logger.LogInformation("Response: {StatusCode}",
context.HttpContext.Response.StatusCode);
return result;
}
}
public class MyEndpoint : IEndpoint<MyRequest, Response<MyResponse>>
{
public void Configure(IEndpointConfiguration config)
{
config.Post("/items").AddFilter<LoggingFilter>();
}
// ...
}

Filters applied to a group affect all endpoints in that group:

public class MyGroup : IEndpointGroup
{
public void Configure(IEndpointGroupConfiguration config)
{
config.Prefix("/api/items").AddFilter<LoggingFilter>();
}
}

IEndpointFilter differs from middleware in that it can be scoped to individual endpoints or groups, rather than applying globally to all requests.

For a FluentValidation example using IEndpointFilter, see the Validation guide. For grouping endpoints, see the Endpoint Groups guide.