As I delve deeper into the Azure Functions ecosystem, I continue to appreciate the concept of using middleware to manage common and repetitive tasks, much like what can be achieved with WebApps.
Unlike WebApps, you can invoke an Azure Function through multiple avenues instead of a request via input bindings. Here are some of the common ones:
Timer Trigger
Blob Trigger
Event Hub Trigger
HTTP Trigger
Queue Trigger
Service Bus Trigger
Generic Webhook
GitHub Webhook
In my case, I want different behaviors to apply to each type of input binding. In other words, I want a custom middleware to be executed based on the type of input binding that activates my Azure Function.
In order to do that, we can use IFunctionsWorkerApplicationBuilder
UseWhen interface in Program.cs to configure the middleware type.
var host = new HostBuilder()
.ConfigureServices(services =>
{
//Register our custom service
services.AddTransient<IDataService, DataService>();
})
.ConfigureFunctionsWorkerDefaults(workerApplication =>
{
workerApplication.UseWhen<MyCustomMiddlewareOne>((context) =>
{
// We want to use this middleware only for http trigger invocations.
return context.FunctionDefinition.InputBindings.Values
.First(a => a.Type.EndsWith("Trigger")).Type == "httpTrigger";
});
workerApplication.UseWhen<MyCustomMiddlewareTwo>((context) =>
{
// We want to use this middleware only for event grid trigger invocations.
return context.FunctionDefinition.InputBindings.Values
.First(a => a.Type.EndsWith("Trigger")).Type == "eventGridTrigger";
});
})
.Build();
host.Run();
By registering my custom middleware as shown above, I ensure that MyCustomMiddlewareOne
is executed only when the input comes from an HTTP Request, while MyCustomMiddlewareTwo
is exclusively used for data originating from an Event Grid topic to which my Azure function subscribes.
If we wish to take this one step further, we can technically assign the middleware to a specific Azure Function name by utilizing the FunctionDefinition's Name property and the input binding direction.
workerApplication.UseWhen<MyCustomMiddlewareOne>((context) =>
{
return
context.FunctionDefinition.InputBindings.Values
.First(a => a.Direction == BindingDirection.In).Type == "httpTrigger"
&& context.FunctionDefinition.Name == nameof(MyAzureFunctionName);
});