Skip to content

Instantly share code, notes, and snippets.

@kshyju
Created May 16, 2022 03:13
Show Gist options
  • Save kshyju/8b9c4a611f773369f14f40578dd74892 to your computer and use it in GitHub Desktop.
Save kshyju/8b9c4a611f773369f14f40578dd74892 to your computer and use it in GitHub Desktop.
Blog-2022_05_15_FunctionsMiddlewareApis
public class ExceptionHandlingMiddleware : IFunctionsWorkerMiddleware
{
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
public ExceptionHandlingMiddleware(ILogger<ExceptionHandlingMiddleware> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
try
{
await next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing invocation");
var httpReqData = await context.GetHttpRequestDataAsync();
if (httpReqData != null)
{
var newHttpResponse = httpReqData.CreateResponse();
await newHttpResponse.WriteAsJsonAsync(new { FooStatus = "Invocation failed!" });
// Update invocation result.
var invocationResult = context.GetInvocationResult();
invocationResult.Value = newHttpResponse;
}
}
}
}
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
await next(context);
// Update the queue message output binding entry value.
var qMsgOutputBinding = context.GetOutputBindings<string>()
.First(a => a.BindingType == "queue");
qMsgOutputBinding.Value = "Updated queue msg from middleware";
}
public class MyBlob
{
public string? Name { set; get; }
}
[Function("HttpTriggerWithBlobInput")]
public void Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
[BlobInput("samples-workitems/myblob.json", Connection = "AzureWebJobsStorage")] MyBlob myBlob)
{
_logger.LogInformation($"Received {myBlob.Name}");
}
public static class HttpTriggerWithMultipleOutputBindings
{
[Function(nameof(HttpTriggerWithMultipleOutputBindings))]
public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req)
{
var response = req.CreateResponse(HttpStatusCode.OK);
response.WriteString("Success!");
return new MyOutputType()
{
Name = "some name",
HttpResponse = response
};
}
}
public class MyOutputType
{
[QueueOutput("functionstesting2", Connection = "AzureWebJobsStorage")]
public string Name { get; set; }
public HttpResponseData HttpResponse { get; set; }
}
public class StampHttpHeaderMiddleware : IFunctionsWorkerMiddleware
{
public async Task Invoke(FunctionContext functionContext, FunctionExecutionDelegate next)
{
var httpReqData = await functionContext.GetHttpRequestDataAsync();
string correlationId;
if (httpReqData!.Headers.TryGetValues("x-correlationId", out var values))
{
correlationId = values.First();
}
else
{
correlationId = Guid.NewGuid().ToString();
}
await next(functionContext);
functionContext.GetHttpResponseData()?.Headers.Add("x-correlationId", correlationId);
}
}
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
var blobBindingMetaData = context.FunctionDefinition
.InputBindings.Values
.FirstOrDefault(a => a.Type == "blob");
if (blobBindingMetaData != null)
{
var bindingResult = await context.BindInputAsync<MyBlob>(blobBindingMetaData);
bindingResult.Value = new MyBlob { Name = "Totally different object" };
}
await next(context);
}
new HostBuilder()
.ConfigureFunctionsWorkerDefaults((appBuilder) =>
{
appBuilder.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()
.Run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment