Azure C# Function — Http request trigger and CosmosDB
In this post Logic Apps — call an Azure Function I described how to call an Azure function from a Logic App.
Today, we will go a little further and look at the function itself. This function is invoked by a Http request. Let’s assume, the Logic App calls an Azure function and sends this body.
{
"cn": "Iowa",
"id": "3c2e494b-ad51-4c51-9b49-bc9788d3f900"
}
The Logic App adds a new document to a CosmosDB database. Then calls the Azure function. Body arguments are used to find the document in the database.
- id — document id,
- cn — county name — this is a partition key.
The function checks if county name equals “Iowa”, adds an isIowa boolean property to the document, then upserts it in the database.
A link to the code on GitHub is placed at the end of the article.
As usual, we need some libraries.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.Cosmos;
Then, we create a class to map a document fetched from Cosmos.
public class IowaSales
{
public string? CountyName { get; set; }
public string? State { get; set; }
public int Quantity { get; set; }
public string? FileName { get; set; }
public string? OperationId { get; set; }
public string? id { get; set; }
public bool isIowa { get; set; }
};
Next, we define a function itself.
[FunctionName("cosmosdb_func_00")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
// here is the function logic
}
Here, we take and refine the body arguments.
string cn = req.Query["cn"];
string id = req.Query["id"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
cn = cn ?? data.cn;
id = id ?? data.id;
Sensitive variables can be saved as environment variables…
string endpointUrl = System.Environment.GetEnvironmentVariable("endpointUrl");
string authorizationKey = System.Environment.GetEnvironmentVariable("authorizationKey");
string databaseName = System.Environment.GetEnvironmentVariable("databaseName");
string containerName = System.Environment.GetEnvironmentVariable("containerName");
…which can be defined in Settings -> Configuration -> Application settings section.
This part of the code is responsible for connecting to CosmosDB, Point Read the document, update it, then upsert.
CosmosClient cosmosClient = new CosmosClient(endpointUrl, authorizationKey);
Database database = cosmosClient.GetDatabase(databaseName);
Container container = database.GetContainer(containerName);
ItemResponse<IowaSales> iowaResponseUpsert = await container.ReadItemAsync<IowaSales>(
id: id, partitionKey: new PartitionKey(cn)
);
IowaSales itemUpsert = iowaResponseUpsert.Resource;
if (itemUpsert.CountyName == "Iowa")
{
itemUpsert.isIowa = true;
}
else
{
itemUpsert.isIowa = false;
}
await container.UpsertItemAsync<IowaSales>(itemUpsert);
At the end, we have a response message which is returned after the function finishes its work.
string responseMessage = string.IsNullOrEmpty(id) || string.IsNullOrEmpty(cn)
? "The CountyName and Id value is null"
: $"Operation completed. CountyName: {cn}, Id: {id}, IsIowa: {itemUpsert.isIowa}";
return new OkObjectResult(responseMessage);
Here is the code on GitHub
Here is a post related to this topic: Azure C# Function — ComosDB trigger and in out binding