Azure Cosmos DB output binding for Azure Functions 2.x and higher

The Azure Cosmos DB output binding lets you write a new document to an Azure Cosmos DB database using the SQL API.

For information on setup and configuration details, see the overview.

Example

Unless otherwise noted, examples in this article target version 3.x of the Azure Cosmos DB extension. For use with extension version 4.x, you need to replace the string collection in property and attribute names with container.

This section contains the following examples:

The examples refer to a simple ToDoItem type:

namespace CosmosDBSamplesV2
{
    public class ToDoItem
    {
        public string id { get; set; }
        public string Description { get; set; }
    }
}

Queue trigger, write one doc

The following example shows a C# function that adds a document to a database, using data provided in message from Queue storage.

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using System;

namespace CosmosDBSamplesV2
{
    public static class WriteOneDoc
    {
        [FunctionName("WriteOneDoc")]
        public static void Run(
            [QueueTrigger("todoqueueforwrite")] string queueMessage,
            [CosmosDB(
                databaseName: "ToDoItems",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection")]out dynamic document,
            ILogger log)
        {
            document = new { Description = queueMessage, id = Guid.NewGuid() };

            log.LogInformation($"C# Queue trigger function inserted one row");
            log.LogInformation($"Description={queueMessage}");
        }
    }
}

Queue trigger, write one doc (v4 extension)

Apps using Cosmos DB extension version 4.x or higher will have different attribute properties which are shown below. The following example shows a C# function that adds a document to a database, using data provided in message from Queue storage.

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using System;

namespace CosmosDBSamplesV2
{
    public static class WriteOneDoc
    {
        [FunctionName("WriteOneDoc")]
        public static void Run(
            [QueueTrigger("todoqueueforwrite")] string queueMessage,
            [CosmosDB(
                databaseName: "ToDoItems",
                containerName: "Items",
                Connection = "CosmosDBConnection")]out dynamic document,
            ILogger log)
        {
            document = new { Description = queueMessage, id = Guid.NewGuid() };

            log.LogInformation($"C# Queue trigger function inserted one row");
            log.LogInformation($"Description={queueMessage}");
        }
    }
}

Queue trigger, write docs using IAsyncCollector

The following example shows a C# function that adds a collection of documents to a database, using data provided in a queue message JSON.

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace CosmosDBSamplesV2
{
    public static class WriteDocsIAsyncCollector
    {
        [FunctionName("WriteDocsIAsyncCollector")]
        public static async Task Run(
            [QueueTrigger("todoqueueforwritemulti")] ToDoItem[] toDoItemsIn,
            [CosmosDB(
                databaseName: "ToDoItems",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection")]
                IAsyncCollector<ToDoItem> toDoItemsOut,
            ILogger log)
        {
            log.LogInformation($"C# Queue trigger function processed {toDoItemsIn?.Length} items");

            foreach (ToDoItem toDoItem in toDoItemsIn)
            {
                log.LogInformation($"Description={toDoItem.Description}");
                await toDoItemsOut.AddAsync(toDoItem);
            }
        }
    }
}

A C# function can be created using one of the following C# modes:

  • In-process class library: compiled C# function that runs in the same process as the Functions runtime.
  • Isolated process class library: compiled C# function that runs in a process isolated from the runtime. Isolated process is required to support C# functions running on .NET 5.0.
  • C# script: used primarily when creating C# functions in the Azure portal.

Queue trigger, save message to database via return value

The following example shows a Java function that adds a document to a database with data from a message in Queue storage.

@FunctionName("getItem")
@CosmosDBOutput(name = "database",
  databaseName = "ToDoList",
  collectionName = "Items",
  connectionStringSetting = "AzureCosmosDBConnection")
public String cosmosDbQueryById(
    @QueueTrigger(name = "msg",
      queueName = "myqueue-items",
      connection = "AzureWebJobsStorage")
    String message,
    final ExecutionContext context)  {
     return "{ id: \"" + System.currentTimeMillis() + "\", Description: " + message + " }";
   }

HTTP trigger, save one document to database via return value

The following example shows a Java function whose signature is annotated with @CosmosDBOutput and has return value of type String. The JSON document returned by the function will be automatically written to the corresponding CosmosDB collection.

    @FunctionName("WriteOneDoc")
    @CosmosDBOutput(name = "database",
      databaseName = "ToDoList",
      collectionName = "Items",
      connectionStringSetting = "Cosmos_DB_Connection_String")
    public String run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET, HttpMethod.POST},
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());

        // Parse query parameter
        String query = request.getQueryParameters().get("desc");
        String name = request.getBody().orElse(query);

        // Generate random ID
        final int id = Math.abs(new Random().nextInt());

        // Generate document
        final String jsonDocument = "{\"id\":\"" + id + "\", " +
                                    "\"description\": \"" + name + "\"}";

        context.getLogger().info("Document to be saved: " + jsonDocument);

        return jsonDocument;
    }

HTTP trigger, save one document to database via OutputBinding

The following example shows a Java function that writes a document to CosmosDB via an OutputBinding<T> output parameter. In this example, the outputItem parameter needs to be annotated with @CosmosDBOutput, not the function signature. Using OutputBinding<T> lets your function take advantage of the binding to write the document to CosmosDB while also allowing returning a different value to the function caller, such as a JSON or XML document.

    @FunctionName("WriteOneDocOutputBinding")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET, HttpMethod.POST},
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            @CosmosDBOutput(name = "database",
              databaseName = "ToDoList",
              collectionName = "Items",
              connectionStringSetting = "Cosmos_DB_Connection_String")
            OutputBinding<String> outputItem,
            final ExecutionContext context) {

        // Parse query parameter
        String query = request.getQueryParameters().get("desc");
        String name = request.getBody().orElse(query);

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());

        // Generate random ID
        final int id = Math.abs(new Random().nextInt());

        // Generate document
        final String jsonDocument = "{\"id\":\"" + id + "\", " +
                                    "\"description\": \"" + name + "\"}";

        context.getLogger().info("Document to be saved: " + jsonDocument);

        // Set outputItem's value to the JSON document to be saved
        outputItem.setValue(jsonDocument);

        // return a different document to the browser or calling client.
        return request.createResponseBuilder(HttpStatus.OK)
                      .body("Document created successfully.")
                      .build();
    }

HTTP trigger, save multiple documents to database via OutputBinding

The following example shows a Java function that writes multiple documents to CosmosDB via an OutputBinding<T> output parameter. In this example, the outputItem parameter is annotated with @CosmosDBOutput, not the function signature. The output parameter, outputItem has a list of ToDoItem objects as its template parameter type. Using OutputBinding<T> lets your function take advantage of the binding to write the documents to CosmosDB while also allowing returning a different value to the function caller, such as a JSON or XML document.

    @FunctionName("WriteMultipleDocsOutputBinding")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET, HttpMethod.POST},
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            @CosmosDBOutput(name = "database",
              databaseName = "ToDoList",
              collectionName = "Items",
              connectionStringSetting = "Cosmos_DB_Connection_String")
            OutputBinding<List<ToDoItem>> outputItem,
            final ExecutionContext context) {

        // Parse query parameter
        String query = request.getQueryParameters().get("desc");
        String name = request.getBody().orElse(query);

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());

        // Generate documents
        List<ToDoItem> items = new ArrayList<>();

        for (int i = 0; i < 5; i ++) {
          // Generate random ID
          final int id = Math.abs(new Random().nextInt());

          // Create ToDoItem
          ToDoItem item = new ToDoItem(String.valueOf(id), name);

          items.add(item);
        }

        // Set outputItem's value to the list of POJOs to be saved
        outputItem.setValue(items);
        context.getLogger().info("Document to be saved: " + items);

        // return a different document to the browser or calling client.
        return request.createResponseBuilder(HttpStatus.OK)
                      .body("Documents created successfully.")
                      .build();
    }

In the Java functions runtime library, use the @CosmosDBOutput annotation on parameters that will be written to Cosmos DB. The annotation parameter type should be OutputBinding<T>, where T is either a native Java type or a POJO.

The following example shows an Azure Cosmos DB output binding in a function.json file and a JavaScript function that uses the binding. The function uses a queue input binding for a queue that receives JSON in the following format:

{
    "name": "John Henry",
    "employeeId": "123456",
    "address": "A town nearby"
}

The function creates Azure Cosmos DB documents in the following format for each record:

{
    "id": "John Henry-123456",
    "name": "John Henry",
    "employeeId": "123456",
    "address": "A town nearby"
}

Here's the binding data in the function.json file:

{
    "name": "employeeDocument",
    "type": "cosmosDB",
    "databaseName": "MyDatabase",
    "collectionName": "MyCollection",
    "createIfNotExists": true,
    "connectionStringSetting": "MyAccount_COSMOSDB",
    "direction": "out"
}

The configuration section explains these properties.

Here's the JavaScript code:

    module.exports = async function (context) {

      context.bindings.employeeDocument = JSON.stringify({
        id: context.bindings.myQueueItem.name + "-" + context.bindings.myQueueItem.employeeId,
        name: context.bindings.myQueueItem.name,
        employeeId: context.bindings.myQueueItem.employeeId,
        address: context.bindings.myQueueItem.address
      });
    };

For bulk insert form the objects first and then run the stringify function. Here's the JavaScript code:

    module.exports = async function (context) {

        context.bindings.employeeDocument = JSON.stringify([
        {
            "id": "John Henry-123456",
            "name": "John Henry",
            "employeeId": "123456",
            "address": "A town nearby"
        },
        {
            "id": "John Doe-123457",
            "name": "John Doe",
            "employeeId": "123457",
            "address": "A town far away"
        }]);
    };

The following example show how to write data to Cosmos DB using an output binding. The binding is declared in the function's configuration file (functions.json), and take data from a queue message and writes out to a Cosmos DB document.

{ 
  "name": "EmployeeDocument",
  "type": "cosmosDB",
  "databaseName": "MyDatabase",
  "collectionName": "MyCollection",
  "createIfNotExists": true,
  "connectionStringSetting": "MyStorageConnectionAppSetting",
  "direction": "out" 
} 

In the run.ps1 file, the object returned from the function is mapped to an EmployeeDocument object, which is persisted in the database.

param($QueueItem, $TriggerMetadata) 

Push-OutputBinding -Name EmployeeDocument -Value @{ 
    id = $QueueItem.name + '-' + $QueueItem.employeeId 
    name = $QueueItem.name 
    employeeId = $QueueItem.employeeId 
    address = $QueueItem.address 
} 

The following example demonstrates how to write a document to an Azure Cosmos DB database as the output of a function.

The binding definition is defined in function.json where type is set to cosmosDB.

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "cosmosDB",
      "direction": "out",
      "name": "doc",
      "databaseName": "demodb",
      "collectionName": "data",
      "createIfNotExists": "true",
      "connectionStringSetting": "AzureCosmosDBConnectionString"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

To write to the database, pass a document object to the set method of the database parameter.

import azure.functions as func

def main(req: func.HttpRequest, doc: func.Out[func.Document]) -> func.HttpResponse:

    request_body = req.get_body()

    doc.set(func.Document.from_json(request_body))

    return 'OK'

Attributes

Both in-process and isolated process C# libraries use attributes to define the function. C# script instead uses a function.json configuration file.

Attribute property Description
ConnectionStringSetting The name of an app setting or setting collection that specifies how to connect to the Azure Cosmos DB account being monitored. For more information, see Connections.
DatabaseName The name of the Azure Cosmos DB database with the collection being monitored.
CollectionName The name of the collection being monitored.
CreateIfNotExists A boolean value to indicate whether the collection is created when it doesn't exist. The default is false because new collections are created with reserved throughput, which has cost implications. For more information, see the pricing page.
PartitionKey When CreateIfNotExists is true, it defines the partition key path for the created collection. May include binding parameters.
*CollectionThroughput When CreateIfNotExists is true, it defines the throughput of the created collection.
PreferredLocations (Optional) Defines preferred locations (regions) for geo-replicated database accounts in the Azure Cosmos DB service. Values should be comma-separated. For example, East US,South Central US,North Europe.
UseMultipleWriteLocations (Optional) When set to true along with PreferredLocations, supports multi-region writes in the Azure Cosmos DB service.

Annotations

From the Java functions runtime library, use the @CosmosDBOutput annotation on parameters that write to Azure Cosmos DB. The annotation supports the following properties:

Configuration

The following table explains the binding configuration properties that you set in the function.json file, where properties differ by extension version:

function.json property Description
connectionStringSetting The name of an app setting or setting collection that specifies how to connect to the Azure Cosmos DB account being monitored. For more information, see Connections.
databaseName The name of the Azure Cosmos DB database with the collection being monitored.
collectionName The name of the collection being monitored.
createIfNotExists A boolean value to indicate whether the collection is created when it doesn't exist. The default is false because new collections are created with reserved throughput, which has cost implications. For more information, see the pricing page.
partitionKey When createIfNotExists is true, it defines the partition key path for the created collection. May include binding parameters.
*collectionThroughput When createIfNotExists is true, it defines the throughput of the created collection.
preferredLocations (Optional) Defines preferred locations (regions) for geo-replicated database accounts in the Azure Cosmos DB service. Values should be comma-separated. For example, East US,South Central US,North Europe.
useMultipleWriteLocations (Optional) When set to true along with preferredLocations, supports multi-region writes in the Azure Cosmos DB service.

See the Example section for complete examples.

Usage

By default, when you write to the output parameter in your function, a document is created in your database. This document has an automatically generated GUID as the document ID. You can specify the document ID of the output document by specifying the id property in the JSON object passed to the output parameter.

Note

When you specify the ID of an existing document, it gets overwritten by the new output document.

Connections

The connectionStringSetting/connection and leaseConnectionStringSetting/leaseConnection properties are references to environment configuration which specifies how the app should connect to Azure Cosmos DB. They may specify:

If the configured value is both an exact match for a single setting and a prefix match for other settings, the exact match is used.

Connection string

The connection string for your database account should be stored in an application setting with a name matching the value specified by the connection property of the binding configuration.

Identity-based connections

If you are using version 4.x or higher of the extension, instead of using a connection string with a secret, you can have the app use an Azure Active Directory identity. To do this, you would define settings under a common prefix which maps to the connection property in the trigger and binding configuration.

In this mode, the extension requires the following properties:

Property Environment variable template Description Example value
Account Endpoint <CONNECTION_NAME_PREFIX>__accountEndpoint The Azure Cosmos DB account endpoint URI. https://<database_account_name>.documents.azure.com:443/

Additional properties may be set to customize the connection. See Common properties for identity-based connections.

When hosted in the Azure Functions service, identity-based connections use a managed identity. The system-assigned identity is used by default, although a user-assigned identity can be specified with the credential and clientID properties. When run in other contexts, such as local development, your developer identity is used instead, although this can be customized. See Local development with identity-based connections.

Grant permission to the identity

Whatever identity is being used must have permissions to perform the intended actions. You will need to assign a role in Azure RBAC, using either built-in or custom roles which provide those permissions.

Important

Some permissions might be exposed by the target service that are not necessary for all contexts. Where possible, adhere to the principle of least privilege, granting the identity only required privileges. For example, if the app only needs to be able to read from a data source, use a role that only has permission to read. It would be inappropriate to assign a role that also allows writing to that service, as this would be excessive permission for a read operation. Similarly, you would want to ensure the role assignment is scoped only over the resources that need to be read.

You will need to create a role assignment that provides access to your database account at runtime. Management roles like Owner are not sufficient. The following table shows built-in roles that are recommended when using the Cosmos DB extension in normal operation. Your application may require additional permissions based on the code you write.

Binding type Example built-in roles
Trigger Cosmos DB Built-in Data Contributor
Input binding Cosmos DB Built-in Data Reader
Output binding Cosmos DB Built-in Data Contributor

Exceptions and return codes

Binding Reference
CosmosDB CosmosDB Error Codes

Next steps