Introduction to Azure Cosmos DB SDKs
The Azure Cosmos DB SDKs provide a convenient and powerful way to interact with your Azure Cosmos DB accounts. These SDKs are designed to be idiomatic to each language, offering a seamless development experience. They abstract away the complexities of the REST API, allowing you to focus on building your application.
Whether you're performing simple data operations or building complex queries, the SDKs offer features like high availability, automatic retries, and efficient connection management.
Supported Languages and Platforms
Azure Cosmos DB offers official SDKs for a variety of popular programming languages, ensuring you can integrate with your preferred development environment.
- .NET: Comprehensive SDK for .NET applications (Core & Framework).
- Node.js: Asynchronous JavaScript SDK for server-side applications.
- Java: Robust SDK for Java developers.
- Python: Idiomatic Python SDK for data scientists and web developers.
- Go: Growing support for Go applications.
- C++: Available for specific use cases.
Azure Cosmos DB .NET SDK
Installation
You can install the latest .NET SDK using NuGet Package Manager. Open your Package Manager Console and run:
Install-Package Microsoft.Azure.Cosmos
Alternatively, use the .NET CLI:
dotnet add package Microsoft.Azure.Cosmos
Getting Started
Here's a basic example of connecting to your Cosmos DB account and creating a container:
using Microsoft.Azure.Cosmos;
using System;
using System.Threading.Tasks;
public class CosmosDbExample
{
private static readonly string EndpointUrl = "YOUR_COSMOS_DB_ENDPOINT";
private static readonly string PrimaryKey = "YOUR_COSMOS_DB_PRIMARY_KEY";
private static readonly string DatabaseId = "MyDatabase";
private static readonly string ContainerId = "MyContainer";
public static async Task Main(string[] args)
{
using (CosmosClient client = new CosmosClient(EndpointUrl, PrimaryKey))
{
Database database = await client.CreateDatabaseIfNotExistsAsync(DatabaseId);
Console.WriteLine($"Database '{database.Id}' created or already exists.");
Container container = await database.CreateContainerIfNotExistsAsync(ContainerId, "/partitionKey");
Console.WriteLine($"Container '{container.Id}' created or already exists.");
Console.WriteLine("Cosmos DB client initialized.");
}
}
}
const { CosmosClient } = require("@azure/cosmos");
const endpoint = "YOUR_COSMOS_DB_ENDPOINT";
const key = "YOUR_COSMOS_DB_PRIMARY_KEY";
const databaseId = "MyDatabase";
const containerId = "MyContainer";
async function setupCosmosDb() {
const client = new CosmosClient({ endpoint, key });
const { database } = await client.databases.createIfNotExists({ id: databaseId });
console.log(`Database '${database.id}' created or already exists.`);
const { container } = await database.containers.createIfNotExists({
id: containerId,
partitionKey: {
paths: ["/partitionKey"]
}
});
console.log(`Container '${container.id}' created or already exists.`);
console.log("Cosmos DB client initialized.");
}
setupCosmosDb();
import com.azure.cosmos.CosmosClient;
import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.CosmosDatabase;
import com.azure.cosmos.CosmosContainer;
public class CosmosDbExample {
private static final String ENDPOINT = "YOUR_COSMOS_DB_ENDPOINT";
private static final String KEY = "YOUR_COSMOS_DB_PRIMARY_KEY";
private static final String DATABASE_ID = "MyDatabase";
private static final String CONTAINER_ID = "MyContainer";
public static void main(String[] args) {
CosmosClient client = new CosmosClientBuilder()
.endpoint(ENDPOINT, KEY)
.buildClient();
CosmosDatabase database = client.createDatabaseIfNotExists(DATABASE_ID).block().getDatabase();
System.out.println("Database '" + database.getId() + "' created or already exists.");
CosmosContainer container = database.createContainerIfNotExists(CONTAINER_ID, "/partitionKey").block().getContainer();
System.out.println("Container '" + container.getId() + "' created or already exists.");
System.out.println("Cosmos DB client initialized.");
}
}
from azure.cosmos import CosmosClient, PartitionKey
ENDPOINT = "YOUR_COSMOS_DB_ENDPOINT"
KEY = "YOUR_COSMOS_DB_PRIMARY_KEY"
DATABASE_ID = "MyDatabase"
CONTAINER_ID = "MyContainer"
client = CosmosClient(ENDPOINT, KEY)
database = client.create_database_if_not_exists(id=DATABASE_ID)
print(f"Database '{database.id}' created or already exists.")
container = database.create_container_if_not_exists(
id=CONTAINER_ID,
partition_key=PartitionKey(path="/partitionKey")
)
print(f"Container '{container.id}' created or already exists.")
print("Cosmos DB client initialized.")
CRUD Operations (.NET Example)
Performing Create, Read, Update, and Delete operations is straightforward with the .NET SDK.
using Microsoft.Azure.Cosmos;
using System;
using System.Threading.Tasks;
using System.Net;
// Assume CosmosClient, Database, and Container are already initialized as in "Getting Started"
public class CrudOperations
{
public async Task PerformCrud(CosmosContainer container)
{
// --- Create ---
var newItem = new { id = "item1", name = "Example Item", category = "Test", partitionKey = "category" };
try
{
ItemResponse createResponse = await container.CreateItemAsync(newItem, new PartitionKey(newItem.partitionKey));
Console.WriteLine($"Created item with id: {createResponse.Resource.id}.");
}
catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.Conflict)
{
Console.WriteLine($"Item with id {newItem.id} already exists.");
}
// --- Read ---
try
{
ItemResponse readResponse = await container.ReadItemAsync(newItem.id, new PartitionKey(newItem.partitionKey));
Console.WriteLine($"Read item: {readResponse.Resource}");
}
catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine($"Item with id {newItem.id} not found.");
}
// --- Update ---
dynamic existingItem = await container.ReadItemAsync(newItem.id, new PartitionKey(newItem.partitionKey));
existingItem.name = "Updated Example Item";
try
{
ItemResponse updateResponse = await container.UpsertItemAsync(existingItem, new PartitionKey(existingItem.partitionKey));
Console.WriteLine($"Updated item with id: {updateResponse.Resource.id}.");
}
catch (CosmosException ex)
{
Console.WriteLine($"Error updating item: {ex.Message}");
}
// --- Delete ---
try
{
ItemResponse deleteResponse = await container.DeleteItemAsync(newItem.id, new PartitionKey(newItem.partitionKey));
Console.WriteLine($"Deleted item with id: {newItem.id}.");
}
catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine($"Item with id {newItem.id} not found for deletion.");
}
}
}
Querying Data (.NET Example)
Azure Cosmos DB supports SQL-like queries. The SDK allows you to construct and execute these queries efficiently.
using Microsoft.Azure.Cosmos;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
// Assume CosmosClient, Database, and Container are already initialized
public class QueryOperations
{
public async Task PerformQuery(CosmosContainer container)
{
// Add some sample data first if not present
var sampleItems = new List<dynamic>
{
new { id = "prod1", name = "Laptop", category = "Electronics", price = 1200, tags = new[] { "tech", "portable" } },
new { id = "prod2", name = "Keyboard", category = "Electronics", price = 75, tags = new[] { "computer", "accessory" } },
new { id = "prod3", name = "Desk Chair", category = "Furniture", price = 300, tags = new[] { "office", "ergonomic" } }
};
foreach (var item in sampleItems)
{
try
{
await container.CreateItemAsync(item, new PartitionKey(item.category));
}
catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.Conflict) {} // Ignore if already exists
}
// --- Basic Query ---
var sqlQueryText = "SELECT * FROM c WHERE c.category = 'Electronics'";
QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText);
FeedIterator queryIterator = container.GetItemQueryIterator(queryDefinition);
Console.WriteLine("\n--- Electronics Products ---");
while (queryIterator.HasMoreResults)
{
FeedResponse response = await queryIterator.ReadNextAsync();
foreach (var item in response)
{
Console.WriteLine($" - {item.name} (Price: {item.price})");
}
}
// --- Query with Parameters ---
var parameterizedQuery = "SELECT VALUE c.name FROM c WHERE c.price > @priceThreshold ORDER BY c.price DESC";
QueryDefinition parameterizedQueryDefinition = new QueryDefinition(parameterizedQuery)
.WithParameter("@priceThreshold", 200);
FeedIterator parameterizedQueryIterator = container.GetItemQueryIterator(parameterizedQueryDefinition);
Console.WriteLine("\n--- Products Pricier Than $200 (Names Only) ---");
while (parameterizedQueryIterator.HasMoreResults)
{
FeedResponse response = await parameterizedQueryIterator.ReadNextAsync();
foreach (var name in response)
{
Console.WriteLine($" - {name}");
}
}
}
}
Performance Tips (.NET SDK)
- Singleton CosmosClient: Use a single instance of
CosmosClient
throughout your application's lifetime. Creating new clients frequently can lead to connection exhaustion and performance degradation. - Partition Key Design: Choose a partition key with high cardinality and even distribution to ensure efficient request routing and avoid hot partitions.
- Indexing Policy: Optimize your indexing policy. By default, Cosmos DB indexes all paths. Consider excluding paths that are not frequently queried or used for filtering to reduce indexing overhead and latency.
- Batching: For multiple create, update, or delete operations on items within the same logical partition, use the Batch API to send them in a single network round trip, reducing latency and RU cost.
- Connection Mode: The SDK defaults to Gateway mode. For better performance, consider using Direct mode where appropriate, especially for scenarios with high throughput requirements.
- Throttling Handling: Implement robust error handling for throttling exceptions (HTTP 429). The SDK has built-in retry logic, but you might need to adjust it based on your application's needs.
Azure Cosmos DB Node.js SDK
Installation
Install the Node.js SDK using npm:
npm install @azure/cosmos
Getting Started
See the "Getting Started" section under the .NET SDK for a conceptual example. The Node.js SDK follows similar patterns for client initialization, database, and container creation.
CRUD Operations (Node.js Example)
const { CosmosClient, CosmosValidationError } = require("@azure/cosmos");
// Assume client, database, and container are already initialized
async function performCrud(container) {
// --- Create ---
const newItem = { id: "nodeItem1", name: "Node Example", category: "Test", partitionKey: "Test" };
try {
const { resource: createdItem } = await container.items.create(newItem);
console.log(`Created item with id: ${createdItem.id}`);
} catch (error) {
if (error.code === 409) {
console.log(`Item with id ${newItem.id} already exists.`);
} else {
console.error("Error creating item:", error);
}
}
// --- Read ---
try {
const { resource: readItem } = await container.item(newItem.id, newItem.partitionKey).read();
console.log("Read item:", readItem);
} catch (error) {
if (error.code === 404) {
console.log(`Item with id ${newItem.id} not found.`);
} else {
console.error("Error reading item:", error);
}
}
// --- Update ---
try {
const { resource: existingItem } = await container.item(newItem.id, newItem.partitionKey).read();
existingItem.name = "Updated Node Example";
const { resource: updatedItem } = await container.item(newItem.id, newItem.partitionKey).replace(existingItem);
console.log(`Updated item with id: ${updatedItem.id}`);
} catch (error) {
console.error("Error updating item:", error);
}
// --- Delete ---
try {
await container.item(newItem.id, newItem.partitionKey).delete();
console.log(`Deleted item with id: ${newItem.id}`);
} catch (error) {
if (error.code === 404) {
console.log(`Item with id ${newItem.id} not found for deletion.`);
} else {
console.error("Error deleting item:", error);
}
}
}
// To run:
// setupCosmosDb().then(container => performCrud(container)).catch(err => console.error(err));
Querying Data (Node.js Example)
const { CosmosClient } = require("@azure/cosmos");
// Assume client, database, and container are already initialized
async function performQuery(container) {
// Add some sample data first if not present
const sampleItems = [
{ id: "nodeProd1", name: "Monitor", category: "Electronics", price: 350, tags: ["display", "office"] },
{ id: "nodeProd2", name: "Mouse", category: "Electronics", price: 25, tags: ["computer", "accessory"] },
{ id: "nodeProd3", name: "Desk Lamp", category: "Furniture", price: 50, tags: ["lighting", "office"] }
];
for (const item of sampleItems) {
try {
await container.items.create(item);
} catch (error) {
if (error.code === 409) {} // Ignore if already exists
else console.error("Error adding sample data:", error);
}
}
// --- Basic Query ---
const querySpec = {
query: "SELECT * FROM c WHERE c.category = 'Electronics'"
};
console.log("\n--- Electronics Products (Node.js) ---");
const { resources: electronicsItems } = await container.items.query(querySpec).fetchAll();
electronicsItems.forEach(item => {
console.log(` - ${item.name} (Price: ${item.price})`);
});
// --- Query with Parameters ---
const parameterizedQuerySpec = {
query: "SELECT VALUE c.name FROM c WHERE c.price > @priceThreshold ORDER BY c.price DESC",
parameters: [
{ name: "@priceThreshold", value: 40 }
]
};
console.log("\n--- Products Pricier Than $40 (Names Only) ---");
const { resources: expensiveProductNames } = await container.items.query(parameterizedQuerySpec).fetchAll();
expensiveProductNames.forEach(name => {
console.log(` - ${name}`);
});
}
// To run:
// setupCosmosDb().then(container => performQuery(container)).catch(err => console.error(err));
Performance Tips (Node.js SDK)
- Singleton CosmosClient: Similar to .NET, reuse your
CosmosClient
instance. - Async/Await: Leverage Node.js's asynchronous nature with
async/await
for non-blocking operations. - Connection Pooling: The SDK manages connection pooling for you when using Direct mode. Ensure you understand its implications.
- Batch Operations: Utilize the
executeBatch
method for efficient bulk operations within a logical partition. - `fetchAll()` vs. Iterators: For large result sets, consider using the iterator pattern (
fetchNext()
) instead offetchAll()
to manage memory.
Azure Cosmos DB Java SDK
Installation
Add the following dependency to your Maven pom.xml
:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-cosmos</artifactId>
<version>4.XX.X</version><!-- Use the latest version -->
</dependency>
Or for Gradle build.gradle
:
implementation 'com.azure:azure-cosmos:4.XX.X' // Use the latest version
Getting Started
See the "Getting Started" section under the .NET SDK for a conceptual example. The Java SDK follows similar patterns for client initialization, database, and container creation.
CRUD Operations (Java Example)
import com.azure.cosmos.*;
import com.azure.cosmos.models.*;
import java.util.UUID;
// Assume client, database, and container are already initialized
public class CrudOperations {
public void performCrud(CosmosContainer container) {
// --- Create ---
String itemId = UUID.randomUUID().toString();
String partitionKeyValue = "JavaTest";
Item itemDefinition = new Item(itemId, partitionKeyValue, "Java Example Item", "Test");
try {
CosmosItemResponse- createResponse = container.createItem(itemDefinition, new PartitionKey(partitionKeyValue), new CosmosItemRequestOptions()).block();
System.out.println("Created item with id: " + createResponse.getItem().getId());
} catch (CosmosException ex) {
if (ex.getStatusCode() == 409) {
System.out.println("Item with id " + itemId + " already exists.");
} else {
System.err.println("Error creating item: " + ex.getMessage());
}
}
// --- Read ---
try {
CosmosItemResponse
- readResponse = container.item(itemId, partitionKeyValue).readItem(new CosmosItemRequestOptions()).block();
System.out.println("Read item: " + readResponse.getItem());
} catch (CosmosException ex) {
if (ex.getStatusCode() == 404) {
System.out.println("Item with id " + itemId + " not found.");
} else {
System.err.println("Error reading item: " + ex.getMessage());
}
}
// --- Update ---
try {
Item existingItem = container.item(itemId, partitionKeyValue).readItem().block().getItem();
existingItem.setName("Updated Java Example Item");
CosmosItemResponse
- updateResponse = container.item(itemId, partitionKeyValue).replaceItem(existingItem, new CosmosItemRequestOptions()).block();
System.out.println("Updated item with id: " + updateResponse.getItem().getId());
} catch (CosmosException ex) {
System.err.println("Error updating item: " + ex.getMessage());
}
// --- Delete ---
try {
container.item(itemId, partitionKeyValue).deleteItem().block();
System.out.println("Deleted item with id: " + itemId);
} catch (CosmosException ex) {
if (ex.getStatusCode() == 404) {
System.out.println("Item with id " + itemId + " not found for deletion.");
} else {
System.err.println("Error deleting item: " + ex.getMessage());
}
}
}
// Simple POJO for demonstration
static class Item {
public String id;
public String partitionKey;
public String name;
public String category;
public Item() {}
public Item(String id, String partitionKey, String name, String category) {
this.id = id;
this.partitionKey = partitionKey;
this.name = name;
this.category = category;
}
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getPartitionKey() { return partitionKey; }
public void setPartitionKey(String partitionKey) { this.partitionKey = partitionKey; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCategory() { return category; }
public void setCategory(String category) { this.category = category; }
@Override
public String toString() {
return "Item{" +
"id='" + id + '\'' +
", partitionKey='" + partitionKey + '\'' +
", name='" + name + '\'' +
", category='" + category + '\'' +
'}';
}
}
}
Querying Data (Java Example)
import com.azure.cosmos.*;
import com.azure.cosmos.models.*;
import java.util.List;
// Assume client, database, and container are already initialized
public class QueryOperations {
public void performQuery(CosmosContainer container) {
// Add some sample data first if not present
try {
container.upsertItem(new CrudOperations.Item("javaProd1", "Electronics", "Tablet", 450, new String[]{"mobile", "display"})).block();
container.upsertItem(new CrudOperations.Item("javaProd2", "Electronics", "Webcam", 80, new String[]{"computer", "video"})).block();
container.upsertItem(new CrudOperations.Item("javaProd3", "Furniture", "Bookshelf", 150, new String[]{"storage", "home"})).block();
} catch (CosmosException ex) {
if (ex.getStatusCode() != 409) { // Ignore conflict
System.err.println("Error adding sample data: " + ex.getMessage());
}
}
// --- Basic Query ---
String queryText = "SELECT * FROM c WHERE c.category = 'Electronics'";
CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
System.out.println("\n--- Electronics Products (Java) ---");
container.queryItems(queryText, options, CrudOperations.Item.class)
.byPage()
.flatMapIterable(CosmosPagedIterable::getResults)
.subscribe(item -> System.out.println(" - " + item.getName() + " (Price: " + item.getPrice() + ")"));
// --- Query with Parameters ---
String parameterizedQuery = "SELECT VALUE c.name FROM c WHERE c.price > @priceThreshold ORDER BY c.price DESC";
CosmosQueryRequestOptions parameterizedOptions = new CosmosQueryRequestOptions()
.addQueryParameter("@priceThreshold", 100);
System.out.println("\n--- Products Pricier Than $100 (Names Only) ---");
container.queryItems(parameterizedQuery, parameterizedOptions, String.class)
.byPage()
.flatMapIterable(CosmosPagedIterable::getResults)
.subscribe(name -> System.out.println(" - " + name));
// Note: In a real app, you'd manage the subscription lifecycle.
// For simplicity, we are letting it run here. You might need to await completion.
try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
}
}
Performance Tips (Java SDK)
- Singleton CosmosClient: As with other SDKs, ensure a single instance of
CosmosClient
is used. - Reactor/RxJava: The Java SDK is built on Project Reactor. Understand its reactive programming model for efficient handling of asynchronous operations.
- Connection Pooling: The SDK manages connection pooling automatically when using Direct mode.
- Batch Operations: Utilize the
executeBatch()
method for atomic batch operations on items within the same logical partition. - Tuning Request Options: Adjust
CosmosQueryRequestOptions
,CosmosItemRequestOptions
, etc., to control consistency levels, partition routing, and other performance-sensitive settings.
Azure Cosmos DB Python SDK
Installation
Install the Python SDK using pip:
pip install azure-cosmos
Getting Started
See the "Getting Started" section under the .NET SDK for a conceptual example. The Python SDK follows similar patterns for client initialization, database, and container creation.
CRUD Operations (Python Example)
from azure.cosmos import CosmosClient, PartitionKey
import uuid
# Assume client, database, and container are already initialized
def perform_crud(container):
# --- Create ---
item_id = str(uuid.uuid4())
partition_key_value = "PythonTest"
new_item = {
"id": item_id,
"partitionKey": partition_key_value,
"name": "Python Example Item",
"category": "Test"
}
try:
created_item = container.create_item(body=new_item)
print(f"Created item with id: {created_item['id']}")
except Exception as e:
if hasattr(e, 'status_code') and e.status_code == 409:
print(f"Item with id {item_id} already exists.")
else:
print(f"Error creating item: {e}")
# --- Read ---
try:
read_item = container.item(item_id, partition_key_value).read()
print(f"Read item: {read_item}")
except Exception as e:
if hasattr(e, 'status_code') and e.status_code == 404:
print(f"Item with id {item_id} not found.")
else:
print(f"Error reading item: {e}")
# --- Update ---
try:
existing_item = container.item(item_id, partition_key_value).read()
existing_item['name'] = "Updated Python Example Item"
updated_item = container.item(item_id, partition_key_value).replace(body=existing_item)
print(f"Updated item with id: {updated_item['id']}")
except Exception as e:
print(f"Error updating item: {e}")
# --- Delete ---
try:
container.item(item_id, partition_key_value).delete()
print(f"Deleted item with id: {item_id}")
except Exception as e:
if hasattr(e, 'status_code') and e.status_code == 404:
print(f"Item with id {item_id} not found for deletion.")
else:
print(f"Error deleting item: {e}")
# To run:
# client = CosmosClient(ENDPOINT, KEY)
# database = client.create_database_if_not_exists(id=DATABASE_ID)
# container = database.create_container_if_not_exists(id=CONTAINER_ID, partition_key=PartitionKey(path="/partitionKey"))
# perform_crud(container)
Querying Data (Python Example)
from azure.cosmos import CosmosClient, PartitionKey
# Assume client, database, and container are already initialized
def perform_query(container):
# Add some sample data first if not present
sample_items = [
{"id": "pyProd1", "name": "Laptop Pro", "category": "Electronics", "price": 1500, "tags": ["tech", "high-end"]},
{"id": "pyProd2", "name": "Mechanical Keyboard", "category": "Electronics", "price": 120, "tags": ["gaming", "typing"]},
{"id": "pyProd3", "name": "Ergonomic Chair", "category": "Furniture", "price": 400, "tags": ["office", "comfort"]},
]
for item in sample_items:
try:
container.upsert_item(body=item)
except Exception as e:
if not (hasattr(e, 'status_code') and e.status_code == 409): # Ignore conflict
print(f"Error adding sample data: {e}")
# --- Basic Query ---
query_spec = {
"query": "SELECT * FROM c WHERE c.category = 'Electronics'"
}
print("\n--- Electronics Products (Python) ---")
items_iterator = container.query_items(query_spec, enable_cross_partition_query=True)
for item in items_iterator:
print(f" - {item['name']} (Price: {item['price']})")
# --- Query with Parameters ---
parameterized_query_spec = {
"query": "SELECT VALUE c.name FROM c WHERE c.price > @priceThreshold ORDER BY c.price DESC",
"parameters": [
{"name": "@priceThreshold", "value": 250}
]
}
print("\n--- Products Pricier Than $250 (Names Only) ---")
expensive_product_names_iterator = container.query_items(parameterized_query_spec, enable_cross_partition_query=True)
for name in expensive_product_names_iterator:
print(f" - {name}")
# To run:
# client = CosmosClient(ENDPOINT, KEY)
# database = client.create_database_if_not_exists(id=DATABASE_ID)
# container = database.create_container_if_not_exists(id=CONTAINER_ID, partition_key=PartitionKey(path="/partitionKey"))
# perform_query(container)
Performance Tips (Python SDK)
- Singleton CosmosClient: Reuse the
CosmosClient
instance. - Iterators: The SDK returns iterators for query results, which are memory-efficient for large datasets.
- `enable_cross_partition_query=True`: Use this when querying across partitions if your partition key is not specified in the query. Be mindful of RU consumption.
- Batching: The Python SDK supports batch operations for efficient bulk data operations.