Azure Functions allows you to inject an instance of the DocumentClient
class to perform, read or write operations on your CosmosDB. This concept is known as input binding and there are multiple bindings available for various Azure resources (See Azure Functions triggers and bindings concepts). Unfortunately, there is no input binding for the new CosmosClient
class that is part of the .NET SDK v3.
In this article, you will learn how you can use the new CosmosClient
within your Azure Functions to leverage the Azure Cosmos DB .NET SDK v3.
Prerequisites
Create a local Functions project
We will use the Azure Functions Core Tools to scaffold the functions project directory.
In the terminal window or from a command prompt, run the following command to create the project:
func init
After you run the command, you have to choose a runtime for the project. We choose dotnet:
Create a function
In addition, we have to create a function that we can invoke later. In this example, we create a dotnet core function with an HTTP trigger by running the following command:
func new --name "MyFunc" --template "HttpTrigger"
Install the Azure Cosmos DB package
In order to work with the CosmosClient
, we have to install the Azure Cosmos DB client library. We can install it using the dotnet add package
command:
dotnet add package Microsoft.Azure.Cosmos
Install the Azure Functions Extension package
The Microsoft.Azure.Functions.Extensions
package enables us to use dependency injection within our Azure Functions. To install it, run the following command:
dotnet add package Microsoft.Azure.Functions.Extensions
Add the Startup class
Now it is time to add a Startup class where we can set up dependency injection for the CosmosClient
. We register the service as a singleton and provide a factory method that retrieves the connection string from the application settings (line 22 – 32).
☝ Note: Azure Functions uses the same service lifetimes as ASP.NET Dependency Injection. The singleton lifetime is recommended for connections like CosmosClient
. It matches the host lifetime and is reused across function executions on that instance.
using System; using azure_functions_cosmosclient; using Microsoft.Azure.Cosmos.Fluent; using Microsoft.Azure.Functions.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; [assembly: FunctionsStartup(typeof(Startup))] namespace azure_functions_cosmosclient { public class Startup : FunctionsStartup { private static readonly IConfigurationRoot Configuration = new ConfigurationBuilder() .SetBasePath(Environment.CurrentDirectory) .AddJsonFile("appsettings.json", true) .AddEnvironmentVariables() .Build(); public override void Configure(IFunctionsHostBuilder builder) { builder.Services.AddSingleton(s => { var connectionString = Configuration["CosmosDBConnection"]; if (string.IsNullOrEmpty(connectionString)) { throw new InvalidOperationException( "Please specify a valid CosmosDBConnection in the appSettings.json file or your Azure Functions Settings."); } return new CosmosClientBuilder(connectionString) .Build(); }); } } }
Set the CosmosDB connection string
In order for the above mentioned factory method to create the CosmosClient
, we must first configure the connection string. Since we want to test the function locally, we can simply add the connection string to the file local.settings.json:
{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet", "CosmosDBConnection": "AccountEndpoint=...." } }
☝ Note: To maintain settings that are used by your Function App on Azure, see Configure function app settings.
Work with the CosmosClient
We will use Constructor injection to make the CosmosClient
available in our function. The following sample demonstrates how the CosmosClient
is injectioned into an HTTP-triggered function that simply creates a database with the name MyCosmosDb:
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Azure.Cosmos; namespace azure_functions_cosmosclient { public class MyFunc { private readonly CosmosClient _cosmosClient; public MyFunc(CosmosClient cosmosClient) { _cosmosClient = cosmosClient; } [FunctionName("MyFunc")] public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req) { await _cosmosClient.CreateDatabaseIfNotExistsAsync("MyCosmosDb"); return new NoContentResult(); } } }
☝ Note: The use of constructor injection requires that we don’t use static classes for our function classes. Also, the function itself must not be static, otherwise it cannot access member variables.
Test the function
To start the Functions project, simply run func start
within your terminal and invoke the function using a GET request:
GET http://localhost:7071/api/MyFunc
After that, you will see the database MyCosmosDB within your ComosDB:
The whole source code is available on GitHub.