Controlling Serialisation of CosmosDB Bindings for Azure Functions
Tags: azure, serverless, azurefunctions, dotnet
Published: 2021-07-11 23:05:25

---
title: Controlling Serialisation of CosmosDB Bindings for Azure Functions
published: true
date: 2021-07-09 04:29:50 UTC
tags: azure,serverless,azurefunctions,dotnet
canonical_url: https://www.aaron-powell.com/posts/2021-07-09-controlling-serialisation-of-cosmosdb-bindings-for-azure-functions/
---

While preparing the content for [the live stream I did today](https://dev.to/aaronpowell/learn-about-f-and-web-development-12f8-temp-slug-4894332) I came across a problem with how the data in CosmosDB was being handled. The sample data set I was using was using camel-case for the field names, such as `correctAnswer` and `incorrectAnswer`, while the casing on the F# record types was pascal-case (`CorrectAnswer` and `IncorrectAnswer`), and this was causing problems in the serialisation/deserialisation of the data.

Since I was using the [input and output bindings for CosmosDB](https://docs.microsoft.com/azure/azure-functions/functions-bindings-cosmosdb-v2?WT.mc_id=dotnet-33392-aapowell) I don’t control the serialisation/deserialisation of the data, so how do we get around this?

Under the hood the bindings use [Newtonsoft.Json](https://www.newtonsoft.com/json) and that has a singleton that we can set the global configuration on, but there’s a problem, _where_ do we do that in a Functions project? we don’t control the startup of the Function, so how do we set the configuration?

After some digging I came across the [`Microsoft.Azure.Functions.Extensions` NuGet package](https://www.nuget.org/packages/Microsoft.Azure.Functions.Extensions) ([source](https://github.com/Azure/azure-functions-dotnet-extensions)) which provides an `FunctionsStartup` class. Now this looks promising.

This class gives us a method `public abstract void Configure(IFunctionsHostBuilder builder)` which will be executed when it initialises the Functions. One of the uses for this class is to do dependency injection, by adding services to the `IFunctionsHostBuilder`, but in our case we don’t need to do that, instead, we can use the method to setup our own configuration for JSON serialisation/deserialisation.

Here’s the F# implementation:

```fsharp
module Startup

open Microsoft.Azure.Functions.Extensions.DependencyInjection
open Newtonsoft.Json
open Newtonsoft.Json.Serialization
open Newtonsoft.Json.Converters

type Startup() =
    inherit FunctionsStartup()

    override _.Configure(_: IFunctionsHostBuilder) : unit =
        let settings = JsonSerializerSettings()
        settings.ContractResolver <- CamelCasePropertyNamesContractResolver()

        DiscriminatedUnionConverter() |> settings.Converters.Add
        StringEnumConverter() |> settings.Converters.Add

        JsonConvert.DefaultSettings <- (fun _ -> settings)

[<assembly: FunctionsStartup(typeof<Startup>)>]
do ()
```

In the `Configure` method we're creating a new instance of the `JsonSerializerSessions`, setting the default contract resolver to be the `CamelCasePropertyNamesContractResolver` and then adding a few additional converters (to play nicer with F# types) before setting this as the default settings.

To make the Function host aware of this class we need to add the assembly-level attribute `FunctionsStartup` (with the `typeof` reference), and now we're controlling how the input and output binding for CosmosDB works.

Hopefully this help you the next time you're wanting to apply global configuration to Azure Functions.