Conditional Middleware usage in Azure Function.

Conditional Middleware usage in Azure Function.

·

2 min read

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 IFunctionsWorkerApplicationBuilderUseWhen 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);
});