Imperative bindings in Azure Functions

In-built bindings provided by Azure Functions for most cases are more than sufficient - you don't have to manage and configure them on your own, all you're supposed to do is to focus on business logic and your codebase. There's a gap however when using bindings from a function.json file - what if I have to create a binding at runtime? Fortunately even this case is covered and you can easily build bindings, even using data delivered in your HTTP request.

Use case

Let's say you'd like to create a function, which fetches data from a CosmosDB instance. The issue here is, that you want to query a particular collection of documents. Normally you'd use following binding:

/
{
  "name": "inputDocument",
  "type": "documentDB",
  "databaseName": "MyDatabase",
  "collectionName": "{collectionId}",
  "connection": "MyAccount_COSMOSDB",     
  "direction": "in"
}

but there's no way to dynamically replace {collectionId} using data from a HTTP request(it works for other triggers like queue for the sqlQuery parameter however). We need to find another way of doing this avoiding building our own repositories and services, which would obscure the whole function.

If you read documentation carefully(especially C# reference), you'll find, that there's a possibility to use dynamic bindings via imperative bindings. The example of usage could like this:

/
using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
{
    ...
}

With such feature we can implement our dynamic CosmosDB collection binding.

Implementing imperative binding in your function

I'll show you an example of using CosmosDB imperative binding in a CSX file, but the same rules apply to regular C# files. The first thing we need here is to reference a binding attribute. In our case it will be DocumentDBAttribute from Microsoft.Azure.WebJobs.Extensions

/
#r "Microsoft.Azure.WebJobs.Extensions.DocumentDB"

Then we have to update function's signature so it accepts Binder type:

/
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, Binder binder, TraceWriter log)

Now we can use imperative binding e.g. to load a collection dynamically:

/
var collection = await binder.BindAsync<IEnumerable<dynamic>>(
        new DocumentDBAttribute("foo", "{dynamic_parameter}"));

The whole function could look like this(don't pay attention to all those dynamics, normally I'd use slightly other structures and methods):

/
#r "Microsoft.Azure.WebJobs.Extensions.DocumentDB"

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, Binder binder, TraceWriter log)
{
	dynamic data = await req.Content.ReadAsAsync<object>();
	using(var collection = await binder.BindAsync<IEnumerable<dynamic>>(
			new DocumentDBAttribute("foo", data.collectionId.Value.ToString()))) 
	{
		var firstDocumentId = collection.First().id.Value.ToString();
		return req.CreateResponse(HttpStatusCode.OK, new {id = firstDocumentId});
	}
}

When I called my function using a following payload:

/
{
    "collectionId": "bar"
}

I'll get following result:

/
{"id":"I am FOO!"}

Summary

This was just a simple example of how you can extend your functions using imperative bindings. The best things is that is allows you to avoid implementing typical patterns usable in traditional web applications and keeps functions relatively clean. Feel free to experiment with those - using dynamic bindings is a really powerful feature and for sure will make your function even more powerful.