title | description | author | ms.topic | ms.date | ms.author | ms.custom |
---|---|---|---|---|---|---|
Azure Cosmos DB output binding for Functions 2.x and higher |
Learn to use the Azure Cosmos DB output binding in Azure Functions. |
craigshoemaker |
reference |
02/24/2020 |
cshoe |
devx-track-csharp, devx-track-python |
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.
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; }
}
}
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}");
}
}
}
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);
}
}
}
}
This section contains the following examples:
The following example shows an Azure Cosmos DB output binding in a function.json file and a C# script 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 C# script code:
#r "Newtonsoft.Json"
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Logging;
public static void Run(string myQueueItem, out object employeeDocument, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
dynamic employee = JObject.Parse(myQueueItem);
employeeDocument = new {
id = employee.name + "-" + employee.employeeId,
name = employee.name,
employeeId = employee.employeeId,
address = employee.address
};
}
To create multiple documents, you can bind to ICollector<T>
or IAsyncCollector<T>
where T
is one of the supported types.
This example refers to a simple ToDoItem
type:
namespace CosmosDBSamplesV2
{
public class ToDoItem
{
public string Id { get; set; }
public string Description { get; set; }
}
}
Here's the function.json file:
{
"bindings": [
{
"name": "toDoItemsIn",
"type": "queueTrigger",
"direction": "in",
"queueName": "todoqueueforwritemulti",
"connectionStringSetting": "AzureWebJobsStorage"
},
{
"type": "cosmosDB",
"name": "toDoItemsOut",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "out"
}
],
"disabled": false
}
Here's the C# script code:
using System;
using Microsoft.Extensions.Logging;
public static async Task Run(ToDoItem[] toDoItemsIn, 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);
}
}
- Queue trigger, save message to database via return value
- HTTP trigger, save one document to database via return value
- HTTP trigger, save one document to database via OutputBinding
- HTTP trigger, save multiple documents to database via OutputBinding
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 + " }";
}
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;
}
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();
}
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 = 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
});
context.done();
};
For bulk insert form the objects first and then run the stringify function. Here's the JavaScript code:
module.exports = 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"
}]);
context.done();
};
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 CosmosDB 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'
In C# class libraries, use the CosmosDB attribute.
The attribute's constructor takes the database name and collection name. For information about those settings and other properties that you can configure, see Output - configuration. Here's a CosmosDB
attribute example in a method signature:
[FunctionName("QueueToDocDB")]
public static void Run(
[QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")] string myQueueItem,
[CosmosDB("ToDoList", "Items", Id = "id", ConnectionStringSetting = "myCosmosDB")] out dynamic document)
{
...
}
Attributes are not supported by C# Script.
The CosmosDBOutput
annotation is available to write data to Cosmos DB. You can apply the annotation to the function or to an individual function parameter. When used on the function method, the return value of the function is what is written to Cosmos DB. If you use the annotation with a parameter, the parameter's type must be declared as an OutputBinding<T>
where T
a native Java type or a POJO.
Attributes are not supported by JavaScript.
Attributes are not supported by PowerShell.
Attributes are not supported by Python.
The following table explains the binding configuration properties that you set in the function.json file and the CosmosDB
attribute.
function.json property | Attribute property | Description |
---|---|---|
type | n/a | Must be set to cosmosDB . |
direction | n/a | Must be set to out . |
name | n/a | Name of the binding parameter that represents the document in the function. |
databaseName | DatabaseName | The database containing the collection where the document is created. |
collectionName | CollectionName | The name of the collection where the document is created. |
createIfNotExists | 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 | PartitionKey | When CreateIfNotExists is true, it defines the partition key path for the created collection. |
collectionThroughput | CollectionThroughput | When CreateIfNotExists is true, it defines the throughput of the created collection. |
connectionStringSetting | ConnectionStringSetting | The name of the app setting containing your Azure Cosmos DB connection string. |
preferredLocations | 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 | UseMultipleWriteLocations | (Optional) When set to true along with PreferredLocations , it can leverage multi-region writes in the Azure Cosmos DB service. |
[!INCLUDE app settings to local.settings.json]
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.
Binding | Reference |
---|---|
CosmosDB | CosmosDB Error Codes |
This section describes the global configuration settings available for this binding in version 2.x. For more information about global configuration settings in version 2.x, see host.json reference for Azure Functions version 2.x.
{
"version": "2.0",
"extensions": {
"cosmosDB": {
"connectionMode": "Gateway",
"protocol": "Https",
"leaseOptions": {
"leasePrefix": "prefix1"
}
}
}
}
Property | Default | Description |
---|---|---|
GatewayMode | Gateway | The connection mode used by the function when connecting to the Azure Cosmos DB service. Options are Direct and Gateway |
Protocol | Https | The connection protocol used by the function when connection to the Azure Cosmos DB service. Read here for an explanation of both modes |
leasePrefix | n/a | Lease prefix to use across all functions in an app. |