CarterCommunity / Carter

Carter is framework that is a thin layer of extension methods and functionality over ASP.NET Core allowing code to be more explicit and most importantly more enjoyable.
MIT License
2.05k stars 172 forks source link

Is it possible to apply a global filter with Carter that applies to all endpoints of all Carter modules? #339

Closed DumboJetEngine closed 2 months ago

DumboJetEngine commented 2 months ago

Is it possible to apply a global filter with Carter that applies to all endpoints of all Carter modules?

I need to post-process each endpoint's return values and modify the response accordingly. One way to do this with asp.net core minimal APIs, is to apply the filter to a MapGroup using MapGroup().AddEndpointFilter<GlobalFilter>(); and then define all endpoints on this group.

But since ICarterModule works with IEndpointRouteBuilder and not RouteGroupBuilder, I guess it is not possible to apply the filter automatically to all Carter modules?

ritasker commented 2 months ago

You can use the RouteGroupBuilder with MapCarter() as it inherits from IEndpointRouteBuilder. For example,

...
var global = app.MapGroup(string.Empty).AddEndpointFilter<MyGlobalFilter>();
global.MapCarter();

app.Run();

public class MyGlobalFilter(ILoggerFactory loggerFactory) : IEndpointFilter {
    private readonly ILogger<MyGlobalFilter> logger = loggerFactory.CreateLogger<MyGlobalFilter>();

    public async ValueTask<object> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
    {
        this.logger.LogInformation("Before Request...");
        var result = await next(context);
        var content = JsonSerializer.Serialize(result);
        this.logger.LogInformation(content);
        this.logger.LogInformation("After Request...");
        return result;
    }
}

Which gave the following log output. image

DumboJetEngine commented 2 months ago

@ritasker This is awesome! Thanks.