Introduction to the Azure Cosmos DB JavaScript SDK
Welcome to the official documentation for the Azure Cosmos DB JavaScript SDK. This SDK provides a high-level, object-oriented interface for interacting with your Azure Cosmos DB resources from your JavaScript applications.
Azure Cosmos DB is a globally distributed, multi-model database service that enables you to read and write data at lightning speed. The JavaScript SDK simplifies common operations such as creating, reading, updating, and deleting data, as well as querying your data using SQL or other supported query languages.
This documentation will guide you through installing, configuring, and using the SDK effectively, covering essential concepts and common use cases.
Installation
You can install the Azure Cosmos DB JavaScript SDK using npm or yarn. We recommend using it within a Node.js environment.
npm install @azure/cosmos
Or using yarn:
yarn add @azure/cosmos
Getting Started
To start using the SDK, you need to import the `CosmosClient` and initialize it with your Cosmos DB account's endpoint and primary key.
import { CosmosClient } from "@azure/cosmos";
const endpoint = "YOUR_COSMOS_DB_ENDPOINT";
const key = "YOUR_COSMOS_DB_PRIMARY_KEY";
const client = new CosmosClient({ endpoint, key });
async function runDemo() {
// Your database and container operations will go here
console.log("CosmosClient initialized successfully.");
}
runDemo().catch(error => {
console.error("Error:", error);
});
Client Configuration
The `CosmosClient` constructor accepts an optional configuration object. This object can include options for:
endpoint: The URI of your Cosmos DB account.key: The primary or secondary read-write key for your account.connectionPolicy: Configure aspects like retry policies, timeouts, and consistency levels.userAgentSuffix: A string to append to the User-Agent header for analytics.
Connection Policy Options
The `connectionPolicy` object allows fine-grained control over network and retry behavior:
requestTimeout: The maximum time in milliseconds to wait for a request to complete.mediaReadTimeout: The maximum time in milliseconds to wait for media content to be read.retryOptions: Defines retry behavior for transient failures.
Database Operations
You can manage databases within your Cosmos DB account.
Create Database
async function createDatabase(databaseId) {
const { database } = await client.databases.create({ id: databaseId });
console.log(`Database ${database.id} created.`);
return database;
}
Read Database
async function readDatabase(databaseId) {
const { database } = await client.databases.read(databaseId);
console.log(`Reading database: ${database.id}`);
return database;
}
List Databases
async function listDatabases() {
const { resources: databases } = await client.databases.list();
console.log("Databases:");
databases.forEach(db => console.log(`- ${db.id}`));
}
Container Operations
Containers are where your items (documents, rows, etc.) are stored. They require a partition key definition.
Create Container
async function createContainer(databaseId, containerId, partitionKeyPath) {
const { database } = await client.databases.createIfNotExists({ id: databaseId });
const { container } = await database.containers.createIfNotExists({
id: containerId,
partitionKey: {
paths: [partitionKeyPath]
}
});
console.log(`Container ${container.id} created in database ${database.id}.`);
return container;
}
Read Container
async function readContainer(databaseId, containerId) {
const { database } = await client.databases.read(databaseId);
const { container } = await database.containers.read(containerId);
console.log(`Reading container: ${container.id}`);
return container;
}
List Containers
async function listContainers(databaseId) {
const { database } = await client.databases.read(databaseId);
const { resources: containers } = await database.containers.list();
console.log(`Containers in ${databaseId}:`);
containers.forEach(container => console.log(`- ${container.id}`));
}
Item Operations
Items are the actual data stored within a container. They are typically JSON documents.
Create Item
To create an item, you need to provide the item's content and its partition key value.
async function createItem(container, newItem) {
const { resource: createdItem } = await container.items.create(newItem);
console.log(`Created item with id: ${createdItem.id}`);
return createdItem;
}
// Example item structure
const myItem = {
id: "unique-item-id-123",
name: "Example Item",
category: "Electronics",
price: 199.99,
tags: ["sample", "test"]
};
Read Item
Retrieve an item using its unique ID and partition key value.
async function readItem(container, itemId, partitionKeyValue) {
const { resource: item } = await container.item(itemId, partitionKeyValue).read();
console.log(`Read item: ${item.id}`);
return item;
}
Update Item
Update an existing item. You can either replace the entire item or partially update it using the `replace` method.
async function updateItem(container, itemId, partitionKeyValue, updatedProperties) {
// Fetch the existing item first to ensure we have the latest version and _etag
const { resource: existingItem } = await container.item(itemId, partitionKeyValue).read();
// Merge updated properties into the existing item
const updatedItemData = { ...existingItem, ...updatedProperties };
const { resource: replacedItem } = await container.item(itemId, partitionKeyValue).replace(updatedItemData);
console.log(`Updated item with id: ${replacedItem.id}`);
return replacedItem;
}
// Example update
const updateData = { price: 219.99, description: "Updated price for the example item." };
Delete Item
Remove an item from the container.
async function deleteItem(container, itemId, partitionKeyValue) {
await container.item(itemId, partitionKeyValue).delete();
console.log(`Deleted item with id: ${itemId}`);
}
Query Items
The SDK supports querying items using a SQL-like query language. You can use `container.items.query()`.
async function queryItems(container, querySpec) {
const { resources: results } = await container.items.query(querySpec).fetchAll();
console.log("Query Results:");
results.forEach(item => console.log(`- ${item.id}`));
return results;
}
// Example query: Find all items in the 'Electronics' category with a price less than 200
const query = {
query: "SELECT * FROM c WHERE c.category = @category AND c.price < @price",
parameters: [
{ name: "@category", value: "Electronics" },
{ name: "@price", value: 200 }
]
};
// To execute:
// queryItems(myContainer, query);
Partition Keys
Partition keys are crucial for distributing your data and ensuring scalability. When creating or modifying containers, you must define a partition key path.
For single-key partition keys, the `partitionKey` object looks like this:
{
kind: "Hash", // or "Range"
paths: ["/yourPartitionKey"]
}
When performing operations on items (like creating, reading, updating, deleting), you must provide the corresponding partition key value for that item.
Transactions
Azure Cosmos DB supports ACID transactions across multiple items within a single logical partition using stored procedures or via the SDK's transaction capabilities (e.g., using the `executeSql` method with a stored procedure).
Change Feed
The change feed provides a persistent, ordered list of modifications to your items. You can process these changes in near real-time.
async function processChangeFeed(container) {
const feedIterator = await container.items.getChangeFeedIterator({
startFromBeginning: true,
partitionKey: "yourPartitionKeyValue" // Optional: specify a partition key
});
while (feedIterator.hasMoreResults()) {
const response = await feedIterator.fetchNext();
response.resources.forEach(change => {
console.log("Change detected:", change);
});
}
}
Bulk Operations
For performance-sensitive scenarios involving many operations, consider using the bulk operations API. This allows you to send multiple create, upsert, or delete requests in a single network call.
async function bulkOperations(container, operations) {
const response = await container.items.bulk(operations);
console.log("Bulk operation results:", response);
return response;
}
// Example operations array:
// const bulkOps = [
// { operationType: "Create", resourceBody: { id: "bulk-item-1", name: "Bulk Item One" } },
// { operationType: "Upsert", resourceBody: { id: "bulk-item-2", name: "Bulk Item Two Updated" } },
// { operationType: "Delete", id: "bulk-item-3", partitionKey: "pkValue" }
// ];
Error Handling
The SDK throws errors for various issues. It's essential to implement robust error handling, especially for network issues or conflicts.
Common Error Status Codes:
409 Conflict: Indicates a conflict, often due to concurrent updates or duplicate IDs.429 Too Many Requests: Rate limiting has been applied. Implement retry logic.404 Not Found: The requested resource does not exist.
try {
await container.item("non-existent-id", "pkValue").read();
} catch (error) {
if (error.code === 404) {
console.log("Item not found.");
} else {
console.error("An unexpected error occurred:", error);
}
}
Advanced Topics
This documentation covers the fundamentals. For more advanced scenarios, explore:
- Stored Procedures and User-Defined Functions (UDFs): For complex server-side logic.
- Triggers: Pre- and post-operation logic execution.
- Indexing Policies: Customizing how Cosmos DB indexes your data for query performance.
- Geospatial Queries: Storing and querying location-based data.
- Multi-region Writes: Configuring your database for high availability and low latency globally.
Refer to the official Azure documentation for comprehensive details and the latest updates.