Integrating Azure Functions with Cosmos DB SQL API in .NET Core 2.2

Zach Gardner .NET Core, Azure, Technology Snapshot, Tutorial Leave a Comment

I am working on a project that leverages both Azure Functions as well as Cosmos DB. In trying to get both of these components wired together, I found that there are very few examples that work with the most recent versions of these components. I also saw examples that could work at a small scale, but don’t show industry-standard best practices, and would lead to performance issues if deployed in an environment with any meaningful traffic.

To that end, I put together this blog post showing how to set up an Azure Functions project in .NET Core 2.2 to integrate with Cosmos DB’s SQL API using its native tooling.

Note: The associated code for this blog post is located on Github at https://github.com/in-the-keyhole/BagelBossAPI, via the In The Keyhole public Github.

Pre-Requisites

In order to get this example solution running, make sure that you have the most recent version of Visual Studio, which as of writing this post, is Visual Studio 2019 16.2.4. Also, make sure that you have the Azure SDK installed along with .NET Core 2.2 SDK.

Also, be sure to download and install the Azure Cosmos DB Emulator. This is what allows a developer to run a simulated Cosmos DB instance on their machine.

Create New Azure Function Solution

The first step is to create a new Azure Function solution. Open Visual Studio, then go to File -> New -> Project.


Search for “Function”, make sure that “Azure Function” shows up, then click Next.

Name the new project BagelBoss.API.API, and name the solution BagelBoss.API. Then click on Create.

For the first trigger, select an Http trigger. Use the defaults for a Storage Emulator and Function access rights. Then click Create.

Once created, right-click on the BagelBoss.API.API project, click on Properties. Then change the Target framework to .NET Core 2.2, if it is not already configured that way. Then save changes.

Next, open up the nuGet Package Manager for the solution. Search for “Microsoft.Azure.Cosmos”. Install the latest version, which at the time of writing this post is 3.1.1.

See Also:  C# On The Client Side With Blazor

Also, search for and install “Microsoft.Azure.Functions.Extensions”. This will allow for dependency injection in the Function App.

Also make sure that all nuGet packages installed by default are updated to their latest versions.

Then create a new class in the project called Startup. This class will be where the Dependency Injection is configured. It needs to extend from Microsoft.Azure.Functions.Extensions.DependencyInjection.FunctionsStartup. There also needs to be a FunctionsStartup attribute added with the fully qualified class name.

Next, add in the following lines to define the resolution of a Cosmos DB Container within the application. This is configured to be a singleton to make sure that the same connection is reused for invocations of the Function App. This reduces the amount of time it takes to process the Function, as it does not have to connect and dispose of the database connection each time it is invoked. Direct connection mode is also used to reduce the round trips on reads and writes.

I have also chosen in this example to create the database and container if they do not already exist. If the control of when databases and containers are created and how they’re configured needs to be managed outside of the application code, those lines can be omitted. I also chose to synchronously use them to simplify the provider method itself as it is synchronous by default.

Then, create a new folder in the project named Entities, and add a new class called Bagel. This class needs to have a property of Id, though it should be written out in the lowercase id for the Cosmos DB SQL API to properly understand it. It will also have a property for Store, which will be used as the partition key. There will also be another property for Schmear to describe what kind of spread needs to be inside the bagel if any. I also find it helpful to setup a getter for the PartitionKey.

Now, go to the generated Http trigger, request an instance of the Container from the Dependency Injector. Also make sure to switch this over to a non-static class and method.

See Also:  .NET Memory Management with dotMemory

Then, inside of the trigger method, create an instance of a Bagel, fill it with some Schmear, save it to the container, then return a response to the caller.

Then, start the Azure Cosmos DB Emulator. Once started, it will pop up a new browser tab/window with configurations that will be needed in later steps. Specifically the URI and Primary Key.

In the Function App project, open up the local.settings.json file. Add in the new properties that start with CosmosDb as specified in this screenshot:

Run the Application

Now that the application has been coded and configured, start the application up. If everything was successful, a console should appear like this:

Follow the instructions on the bottom to execute a HTTP GET against the URL the function is listening for. Specify a name in the URL that will be used as the store’s name. Then observe the response.

To see the data saved to the Cosmos DB emulator, open its Data Explorer. Then go to Explorer, expand the BagelBoss database, open the Bagels container, click on Items. Note the items that show up on the right side.

Wrap Up

Through the course of this blog post, I showed how to create a new Azure Function App, and have its data sourced from an Azure Cosmos DB Emulator.

These two technologies represent the best-in-brand PaaS offerings from Azure, so it is easy to see how developers could accelerate the delivery of functionality by moving toward a serverless programming model like Azure services provide.

What Do You Think?