Search code examples
c#.netasp.net-coreminimal-apis

ASP.NET Core - Is it possible to apply a filter for all minimal API endpoints?


I want to apply a filter to all asp.net core minimal API endpoints.

The reason I want to do this is to post-process the return values of the endpoint. Something like this:

    public class GlobalFilter : IEndpointFilter
    {
        private ILogger _logger;

        public GlobalValidationFilter(ILogger<GlobalValidationFilter> logger)
        {
            _logger = logger;
        }

        public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext invocationContext, EndpointFilterDelegate next)
        {
            try
            {
                var res = await next(invocationContext);
                var result = res as Result;
                if(result is not null)
                {
                    // Here, access the `result` members and modify the return value accordingly...
                }

                return Results.Problem();
            }
            catch (Exception ex)
            {
                return Results.Problem(ex.ToString());
            }
        }
    }
            app
                .MapPost("api/document/getById", async ([FromBody] GetDocumentRequest request) =>
                {
                    var result = ...result-producing call...;
                    return result;
                })
                .AddEndpointFilter<GlobalFilter>() // Manually assigning the filter.
                ...
                ...;

This appears to work, but I would have to remember to set the filter manually every time. Is there a way to apply this filter to all endpoints automatically?

Alternatively, is it possible to achieve the same thing with another method? From what I have seen, using a middleware does not allow you to inspect the endpoint return values, but only handle thrown exceptions.


Solution

  • You can apply the filter to a MapGroup, the MapGroup can point to all your minimal endpoints.

    Example:

    public static class GroupEndPointsExt
    {
        public static RouteGroupBuilder MapMinimalApi(this RouteGroupBuilder group)
        {
          group.MapPost("document/getById", async ([FromBody] GetDocumentRequest request) =>
          {
                        var result = ...result-producing call...;
                        return result;
           });
    //add other minimal endpoints here where global filter will apply
            return group;
        }
    }
    

    Then in your Program.cs apply the GlobalFilter to the route group that encompasses all your minimal endpoints defined in method MapMinimalApi

    app.MapGroup("api").MapMinimalApi().AddEndpointFilter<GlobalFilter>();
    //Global filter will apply to all endpoints in this route group
    //all endpoints in this route group will use path prefixed with api