Skip to content

Support global endpoint filters and metadata on WebApplication #59755

@captainsafia

Description

@captainsafia

Background and Motivation

In the past, there have been requests to support adding endpoint filters at the global level (see #43237). More recently, the need for global filters has emerged as part of the work to support a source generator-based validation implementation in minimal APIs (see #46349).

Endpoint filters are implemented on top of ASP.NET Core's conventions API and the IEndpointConventionBuilder. To support global filters, we'll need to expose an API for accessing an underlying IEndpointConventionBuilder on the top-level WebApplication.

Proposed API

// Assembly: Microsoft.AspNetCore
namespace Microsoft.AspNetCore.Builder;

public sealed class WebApplication : IHost, IApplicationBuilder, IEndpointRouteBuilder, IAsyncDisposable
{
+  public IEndpointConventionBuilder Conventions { get; }
}

Usage Examples

var app = WebApplication.Create();

// Register parameter validations for minimal APIs globally
app.Conventions.WithValidation();

// Disable anti-forgery checks on form-based endpoints during development
if (app.Environment.IsDevelopment())
{
  app.Conventions.DisableAntiforgery();
}

// Require authorization on all endpoints in the application
app.Conventions.RequireAuthorization();

app.MapGet("/", () => "Hello world!");

app.Run();

Alternative Designs

Instead of exposing the IEndpointConventionBuilder as a property on the WebApplication class, we can consider implementing the IEndpointConventionBuilder interface directly on the class.

// Assembly: Microsoft.AspNetCore
namespace Microsoft.AspNetCore.Builder;

public sealed class WebApplication : IHost, IApplicationBuilder, IEndpointRouteBuilder, IAsyncDisposable, IEndpointConventionBuilder
{
+  public void Add(Action<EndpointBuilder> convention) { }
+  public void Finally(Action<EndpointBuilder> finallyConvention) { }
}

However, there's hesitation around having WebApplication implement the IEndpointConventionBuilder which is an interface with multiple extension methods (ref) that might pollute the API surface for the WebApplication. Isolating these extension methods to a property keeps the Intellisense on WebApplication clean. On the other hand, there are discoverability questions around the Conventions property.

Alternatively, we can consider exposing a deconstructor on the WebApplication class that allows the user to pull out the underlying IEndpointConventionBuillder.

// Assembly: Microsoft.AspNetCore
namespace Microsoft.AspNetCore.Builder;

public sealed class WebApplication : IHost, IApplicationBuilder, IEndpointRouteBuilder, IAsyncDisposable
{
+  public void Deconstruct(out IEndpointConventionBuilder conventions) { }
}

Risks

  • The name Conventions comes from an implementation details of the framework and is not as familiar to users as related terms like "filter" and "metadata", which map to conventions under the hood. This might impact the discoverability of this feature.
  • Supporting global filters on WebApplication means that users will need to understand the distinction between global middleware and global filters. We'll need to make sure that the distinction is clear to users who might not be familiar with the different pipelines.
  • Since conventions are global and applied to all RouteEndpoints there is a chance that users can use the API in a way that results in non-sensical permutations. For example, a user can invoke app.Conventions.WithGroupName("global") to add a global group name to all endpoints. This concept only makes sense in endpoints that use link-generation or OpenAPI and would be non-sensical of Blazor or SignalR endpoints.

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etc

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions