azureazure-functionsazure-cosmosdb.net-6.0azure-cosmosdb-changefeed

Have the Document class when using CosmosDBTrigger been deprecated?


Have the Document class in the Microsoft.Azure.Documents namespace been deprecated when developing isolated Azure functions?

I have recently migrated/upgraded a .NET6 Azure Function (v4) from running in-proccess to out-of-process a.k.a isolated (dotnet-isolated).

My Azure function is using the CosmosDBTrigger in order to act on changefeed events.

One of the required steps to migrate is to package references:

Core packages:

The following packages are required to run your .NET functions in an isolated process:

Extensions packages:

Because functions that run in a .NET isolated process use different binding types, they require a unique set of binding extension packages.

Since my Azure function uses CosmosDBTrigger I also need this package reference:

I have tested to create a new Azure Function using the .NET6 Isolated template project in Visual Studio 2022 to compare my code with the sample code. No other package references are required.

Now I can't use IReadOnlyList<Document> since the following old code need to be upgraded from:

[FunctionName("CosmosTrigger")]
    public static void Run([CosmosDBTrigger(
        databaseName: "ToDoItems",
        collectionName: "Items",
        ConnectionStringSetting = "CosmosDBConnection",
        LeaseCollectionName = "leases",
        CreateLeaseCollectionIfNotExists = true)]IReadOnlyList<Document> documents,
        ILogger log)
    {
        if (documents != null && documents.Count > 0)
        {
            log.LogInformation($"Documents modified: {documents.Count}");
            log.LogInformation($"First document Id: {documents[0].Id}");
        }
    }

To this:

  public class ToDoItem
  {
      public string Id { get; set; }
      public string Description { get; set; }
  }

[Function("CosmosTrigger")]
    public static void Run([CosmosDBTrigger(
        databaseName: "databaseName",
        containerName: "containerName",
        Connection = "CosmosDBConnectionSetting",
        LeaseContainerName = "leases",
        CreateLeaseContainerIfNotExists = true)]IReadOnlyList<ToDoItem> input, ILogger log)
    {
        if (input != null && input.Count > 0)
        {
            log.LogInformation("Documents modified " + input.Count);
            log.LogInformation("First document Id " + input[0].Id);
        }
    }

Makes no sense deserializing incoming changefeed events to a custom POCO class like ToDoItem as an example, the big strength with the Document class was the ability to deserialize the changefeed events into different custom POCO classes depending on the underlaying JSON structure of the CosmosDB document.

I'm not sure how to handle future breaking changes to my CosmosDB documents, currently we have a documentVersion property containing a integer value in order to deserialize the changefeed events into the correct custom POCO class.

The example code above would cause a runtime exception if deserializing JSON not mathing the data structure of the ToDoItem class.


Solution

  • First, seems like you are using the 4.0.0-preview Extension, keep in mind this is a preview extension, not meant for production.

    Deserializing to a custom POCO has been a big ask for a lot of customers. Having to pay the performance cost of going from Document to a business class was not ideal for many people. It does make sense to give people the freedom to remove double serialization from their workflows.

    If what you want is to have a generic class to deserialize to, you can follow the V3 migration guide and a good replacement for Document is JObject. Or if you are using System.Text.Json as serialization engine, JsonDocument.