Route handler filter in minimal APIs of ASP.NET Core 7
Use the ASP.NET Core 7 API filters to modify and shorten the request processing process.
ASP.NET Core 6 introduces a simplified hosting model which allows us to create lightweight APIs with very few dependencies. ASP.NET Core 6’s minimal APIs don’t require controllers and do not support many useful ASP.NET features. Filters is one of these features that are missing.
ASP.NET Core 7 is now available in a Release Candidat. We can use the new IRouteHandlerFilter Interface to add filters to our minimal APIs. These filters can be used as a way to modify or shorten the request processing process or to add response objects to the request.
This article will show you how to use route handler filters in ASP.NET Core 7 when creating minimal API apps. Visual Studio 2022 Preview is required to use the code examples in this article.
Visual Studio 2022 allows you to create a ASP.NET Core 7 minimum Web API project.
Let’s first create an ASP.NET Core 7 Project in Visual Studio 2022 Preview. These are the steps to follow:
- Launch Visual Studio 2022 Preview IDE.
- Click on “Create a new project”
- Select “ASP.NET Core Web API” in the “Create a new project” window.
- Click Next.
- In the “Configure a new project” window, enter the name and the location of the project.
- Depending on your preferences, you can also check the box “Place solution or project in the same directories”
- Next
- The “Additional Information” window that appears next should be unchecked. We’ll only use minimal APIs in this instance, so check the box that says “Use …” controllers”. Set the “Authentication Type” to “None” (default).
- As we will not be using these features, ensure that you have unchecked the boxes “Enable Docker,” Configure for HTTPS,” or “Enable Open API support”.
- Click on Create.
This ASP.NET Core 7 Web API Project will be used to create a minimal API, and to implement route handler filters.
What are filters? What are filters?
Filters enable you to execute code at specific stages of the request processing process. A filter is simply a piece or code that is executed either before or after an action method has been executed. A filter could be used to log each time someone visits a website or validate the parameters sent to an Endpoint.
Filters have many benefits.
- Filters can make your application safer by allowing you reject requests that do not meet certain criteria (including authorisation).
- Filters are useful for cleaning up code and creating reusable classes and functions.
- Filters enable you to concentrate on the business logic of your app instead of writing code for cross-cutting issues such as exception handling, security, and logging.
Why use filters in minimal APIs when possible?
To write the following code, you can use filters in minimal APIs.
- Execute code before an endpoint handler and after it.
- When an endpoint handler runs, inspect and edit the parameters.
- Examine the behavior of an endpoint handler.
- Log the request and reply metadata.
- Make sure that your request targets an API version supported by the company.
- Validate the request and specify the parameters.
The IRouteHandlerFilter interface is available in ASP.NET Core 7.
The IRouteHandlerFilter interface can be used to modify or respond to a request, or to shorten the request processing process. Cross-cutting concerns like authorization, authentication, and log can be added. Here’s a quick overview of what this interface can do:
- Create custom logic to handle incoming requests
- You can intercept a request and modify it as necessary.
- Before the reply is sent, make any changes.
- You can short-circuit a request so that all remaining action filters are not executed.
This code snippet shows the IRoutehandler interface.
namespace Microsoft.AspNetCore.Http; public interface IRouteHandlerFilter { ValueTaskInvokeAsync( RouteHandlerInvocationContext context, RouteHandlerFilterDelegate next); }
In ASP.NET Core 7, create a custom route handler filter
As shown in the code listing below, you can create a custom filter type via the IRouteHandlerFilter Interface.
public class DemoFilter : IRouteHandlerFilter { private ILogger _logger; public DemoFilter(ILoggerFactory loggerFactory) _logger = logger; public async ValueTaskInvokeAsync(RouteHandlerInvocationContext context, RouteHandlerFilterDelegate next) { var text = context.GetParameters[0]; if (text.Equals("Error")) { _logger.LogInformation("Error."); return Results.Problem("This is a minimal example of an error. "); } _logger.LogInformation("Success."); return await next(context); } }
Next, register the filter in Program.cs using the code snippet below.
builder.Services.AddSingleton();
It is possible to register a filter by using the RouteHandlerFilterDelegate or the AddFilter extension method. We will use the AddFilter extension in this example. The following code snippet should be placed in Program.cs.
app.MapGet("/v1/MyDemoEndpointtext", "Hello") .AddFilter();
In ASP.NET Core 7, create a short circuit filter
Sometimes, you might need to shorten the request processing process. Let’s take, for example, a microservices-based app that isn’t responding to one service. All requests to this service would be rejected. You could instead shorten the request processing pipeline to allow you to use another service that is more efficient.
To avoid excessive processing, short-circuiting is often desired. If a request for static files like HTML, CSS and JavaScript is received, you can create a filter to intercept, handle, then serve the request, while short-circuiting all other parts of the pipeline. Short-circuiting is a method that stops the request processing pipeline, redirects the request to another service or method.
A circuit breaker pattern is another example of shortcircuiting in microservices-based apps. This prevents an application’s failure to perform an operation. If you experience problems with a service, or a method of service, circuit breakers will redirect your requests to a fallback service. Circuit breakers can be used to redirect requests to fallback services and methods if a service fails.
This is how to implement a short-circuit filter in your minimal API.
public class MyShortCircuitFilter: IRouteHandlerFilter { public ValueTask InvokeAsync( RouteHandlerInvocationContext context, RouteHandlerFilterDelegate next) { return new ValueTask(Results.Json (new Message = "Terminated" )); }|(Results.Json.new Message = Terminated }));}
Filters enable you to run custom codes before or after a specific point in the request processing process. Filters also prevent code duplication across actions. The IRouteHandlerFilter Interface can be applied to a whole route or a single handler. This allows you to access the request object, modify it as needed, and then send the response.