Home

Awesome

Azure Functions HTTP Extensions

Wiki Nuget

Logo

This C# library extends the Azure Functions HTTP Trigger and adds useful extensions to make working with HTTP requests more fluent. It allows you to add HTTP parameters from headers, query parameters, body and form fields directly to the function signature. It also adds some boilerplate code to take advantage of Function Filters in v2 Functions, allowing you to specify cross-cutting Exception handling tasks combined with an overridable error response formatter.

Also see the NSwag.AzureFunctionsV2 project which is a Swagger Generator supplementing NSwag, built specifically to produce Swagger JSON from Azure Function Apps and fully supports the HttpExtensions project, allowing you to pretty much use a convenient syntax with HTTP request parameters defined in the Function signature and getting the full benefits of an automatic Swagger JSON generation from the Function App assembly. These two projects combined make Azure Functions a different experience, and building APIs with Functions is now less of a hassle.

Features

Example usage

[HttpAuthorize(Scheme.Jwt)]
[FunctionName("TestFunction")]
public static async Task<IActionResult> TestFunction (
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "mymethod/{somestring}")] HttpRequest req,
    string somestring,
    [HttpQuery(Required = true)]HttpParam<string> stringParam,
    [HttpQuery]HttpParam<List<int>> intParams,
    [HttpQuery]HttpParam<TestEnum> enumParam,
    [HttpBody]HttpParam<MyClass> myBodyObject,
    [HttpHeader(Name = "x-my-header")]HttpParam<string> customHeader,
    [HttpToken]HttpUser user,
    ILogger log)
{
	string blah = stringParam; // implicit operator

	foreach(var x in intParams.Value) {
		// ...
	}

    return new OkObjectResult("");
}

See the wiki for details on the attributes and parameters.

Error responses

Assuming we're using the default implementation of IHttpExceptionHandler and the above function was called with improper values in intParams, the function returns 400, with JSON content:

HTTP/1.1 400 Bad Request
Date: Sun, 13 Jan 2019 16:12:30 GMT
Content-Type: application/json
Server: Kestrel
Transfer-Encoding: chunked

{
  "message": "Failed to assign parameter 'intParams' value",
  "parameter": "intParams"
}

This functionality is provided by the exception filter. Note: the exception filter is an optional feature and needs to be enabled manually. Read more about this in the wiki

Further examples can be found from the example project AzureFunctionsV2.HttpExtensions.Examples.FunctionApp and documentation on exception handling from the wiki.

Documentation

The project comes with an example project in the sources AzureFunctionsV2.HttpExtensions.Examples.FunctionApp as well as with some wiki documentation. Please check the wiki before opening an issue.

How was this made?

By using Binding attributes it's possible to create Function parameters that act as placeholders for the HttpRequest parameters, which are then assigned the proper values just before running the Function using Function Filters.

The caveat is that it's necessary to use a container (HttpParam<>) for the parameters because the parameter binding happens before we can get access to the HttpRequest. The values get bound kind of too early for this to work, but we save the day by having access to both the placeholder containers and the HttpRequest upon the Function Filter running phase, which gets run just before the function gets called so we may assign the values to each HttpParam's Value property there.

It's worth noticing that the Function Filters are a somewhat new feature and have been marked as obsolete - however they're not obsolete, they have only been marked obsolete due to the team not having fully finished the features to consider them complete. (see https://github.com/Azure/azure-webjobs-sdk/issues/1284)

Also it's worth saying that the Azure Functions Exception Filter has no control over the return value of the Function and therefore a different approach has been taken in this library to tackle this issue. Read more about it in the wiki.