Search code examples
azureazure-functions

Adding custom headers to Azure Functions response


I'm working on an Azure Function App (v2), which has a number of different functions inside the same Function App.

It is going to be deployed in multiple Azure regions, and I would like to add a custom header, that indicates which region served the request.

I know that I can let each function return HttpResponseMessage which can contain custom headers. Instead of duplicating that code to each function, I would like to make it centralized in the entire Function App project. Another drawback of returning HttpResponseMessage is that I would like to use IActionResult, so I can use JsonResult or OkObjectResult and similar return types.

With an ASP.NET MVC project, I could add a middleware which added the header or add the headers using web.config. Neither seems to be possible in a Function App.

How can this be done without having to return HttpResponseMessage and adding the header inside each function's Run method?


Solution

  • It is now possible to inject middleware that can add custom headers to functions responses.

    Registration

    public static void Main()
    {
      var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults(workerApplication =>
        {
          workerApplication.UseWhen<StampHttpHeaderMiddleware>((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";
          });
        })
       .Build();
      host.Run();
    

    Implementation

    internal sealed class StampHttpHeaderMiddleware : IFunctionsWorkerMiddleware
    {
        public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
        {
          context.GetHttpResponseData()?.Headers.Add("x-myCustomHeader", "custom header value");
          await next(context);
        }
    }
    

    (code is adapted from the GitHub sample)