azure-cosmos-ts

Azure Cosmos DB JavaScript/TypeScript SDK (@azure/cosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: "Cosmos DB", "@azure/cosmos", "CosmosClient", "document CRUD", "NoSQL queries", "bulk operations", "partition key", "container.items".

npx skills add https://github.com/microsoft/skills --skill azure-cosmos-ts

@azure/cosmos (TypeScript/JavaScript)

Data plane SDK for Azure Cosmos DB NoSQL API operations — CRUD on documents, queries, bulk operations.

⚠️ Data vs Management Plane

  • This SDK (@azure/cosmos): CRUD operations on documents, queries, stored procedures
  • Management SDK (@azure/arm-cosmosdb): Create accounts, databases, containers via ARM

Installation

npm install @azure/cosmos @azure/identity

Current Version: 4.9.0
Node.js: >= 20.0.0

Environment Variables

COSMOS_ENDPOINT=https://<account>.documents.azure.com:443/
COSMOS_DATABASE=<database-name>
COSMOS_CONTAINER=<container-name>
# For key-based auth only (prefer AAD)
COSMOS_KEY=<account-key>
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production

Authentication

Microsoft Entra Token Credential (Recommended)

import { CosmosClient } from "@azure/cosmos";
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";

// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]});
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/javascript/api/overview/azure/identity-readme?view=azure-node-latest#credential-classes
// const credential = new ManagedIdentityCredential();

const client = new CosmosClient({
  endpoint: process.env.COSMOS_ENDPOINT!,
  aadCredentials: credential,
});

Key-Based Authentication

import { CosmosClient } from "@azure/cosmos";

// Option 1: Endpoint + Key
const client = new CosmosClient({
  endpoint: process.env.COSMOS_ENDPOINT!,
  key: process.env.COSMOS_KEY!,
});

// Option 2: Connection String
const client = new CosmosClient(process.env.COSMOS_CONNECTION_STRING!);

Resource Hierarchy

CosmosClient
└── Database
    └── Container
        ├── Items (documents)
        ├── Scripts (stored procedures, triggers, UDFs)
        └── Conflicts

Core Operations

Database & Container Setup

const { database } = await client.databases.createIfNotExists({
  id: "my-database",
});

const { container } = await database.containers.createIfNotExists({
  id: "my-container",
  partitionKey: { paths: ["/partitionKey"] },
});

Create Document

interface Product {
  id: string;
  partitionKey: string;
  name: string;
  price: number;
}

const item: Product = {
  id: "product-1",
  partitionKey: "electronics",
  name: "Laptop",
  price: 999.99,
};

const { resource } = await container.items.create<Product>(item);

Read Document

const { resource } = await container
  .item("product-1", "electronics") // id, partitionKey
  .read<Product>();

if (resource) {
  console.log(resource.name);
}

Update Document (Replace)

const { resource: existing } = await container
  .item("product-1", "electronics")
  .read<Product>();

if (existing) {
  existing.price = 899.99;
  const { resource: updated } = await container
    .item("product-1", "electronics")
    .replace<Product>(existing);
}

Upsert Document

const item: Product = {
  id: "product-1",
  partitionKey: "electronics",
  name: "Laptop Pro",
  price: 1299.99,
};

const { resource } = await container.items.upsert<Product>(item);

Delete Document

await container.item("product-1", "electronics").delete();

Patch Document (Partial Update)

import { PatchOperation } from "@azure/cosmos";

const operations: PatchOperation[] = [
  { op: "replace", path: "/price", value: 799.99 },
  { op: "add", path: "/discount", value: true },
  { op: "remove", path: "/oldField" },
];

const { resource } = await container
  .item("product-1", "electronics")
  .patch<Product>(operations);

Queries

Simple Query

const { resources } = await container.items
  .query<Product>("SELECT * FROM c WHERE c.price < 1000")
  .fetchAll();

Parameterized Query (Recommended)

import { SqlQuerySpec } from "@azure/cosmos";

const querySpec: SqlQuerySpec = {
  query: "SELECT * FROM c WHERE c.partitionKey = @category AND c.price < @maxPrice",
  parameters: [
    { name: "@category", value: "electronics" },
    { name: "@maxPrice", value: 1000 },
  ],
};

const { resources } = await container.items
  .query<Product>(querySpec)
  .fetchAll();

Query with Pagination

const queryIterator = container.items.query<Product>(querySpec, {
  maxItemCount: 10, // Items per page
});

while (queryIterator.hasMoreResults()) {
  const { resources, continuationToken } = await queryIterator.fetchNext();
  console.log(`Page with ${resources?.length} items`);
  // Use continuationToken for next page if needed
}

Cross-Partition Query

const { resources } = await container.items
  .query<Product>(
    "SELECT * FROM c WHERE c.price > 500",
    { enableCrossPartitionQuery: true }
  )
  .fetchAll();

Bulk Operations

Execute Bulk Operations

import { BulkOperationType, OperationInput } from "@azure/cosmos";

const operations: OperationInput[] = [
  {
    operationType: BulkOperationType.Create,
    resourceBody: { id: "1", partitionKey: "cat-a", name: "Item 1" },
  },
  {
    operationType: BulkOperationType.Upsert,
    resourceBody: { id: "2", partitionKey: "cat-a", name: "Item 2" },
  },
  {
    operationType: BulkOperationType.Read,
    id: "3",
    partitionKey: "cat-b",
  },
  {
    operationType: BulkOperationType.Replace,
    id: "4",
    partitionKey: "cat-b",
    resourceBody: { id: "4", partitionKey: "cat-b", name: "Updated" },
  },
  {
    operationType: BulkOperationType.Delete,
    id: "5",
    partitionKey: "cat-c",
  },
  {
    operationType: BulkOperationType.Patch,
    id: "6",
    partitionKey: "cat-c",
    resourceBody: {
      operations: [{ op: "replace", path: "/name", value: "Patched" }],
    },
  },
];

const response = await container.items.executeBulkOperations(operations);

response.forEach((result, index) => {
  if (result.statusCode >= 200 && result.statusCode < 300) {
    console.log(`Operation ${index} succeeded`);
  } else {
    console.error(`Operation ${index} failed: ${result.statusCode}`);
  }
});

Partition Keys

Simple Partition Key

const { container } = await database.containers.createIfNotExists({
  id: "products",
  partitionKey: { paths: ["/category"] },
});

Hierarchical Partition Key (MultiHash)

import { PartitionKeyDefinitionVersion, PartitionKeyKind } from "@azure/cosmos";

const { container } = await database.containers.createIfNotExists({
  id: "orders",
  partitionKey: {
    paths: ["/tenantId", "/userId", "/sessionId"],
    version: PartitionKeyDefinitionVersion.V2,
    kind: PartitionKeyKind.MultiHash,
  },
});

// Operations require array of partition key values
const { resource } = await container.items.create({
  id: "order-1",
  tenantId: "tenant-a",
  userId: "user-123",
  sessionId: "session-xyz",
  total: 99.99,
});

// Read with hierarchical partition key
const { resource: order } = await container
  .item("order-1", ["tenant-a", "user-123", "session-xyz"])
  .read();

Error Handling

import { ErrorResponse } from "@azure/cosmos";

try {
  const { resource } = await container.item("missing", "pk").read();
} catch (error) {
  if (error instanceof ErrorResponse) {
    switch (error.code) {
      case 404:
        console.log("Document not found");
        break;
      case 409:
        console.log("Conflict - document already exists");
        break;
      case 412:
        console.log("Precondition failed (ETag mismatch)");
        break;
      case 429:
        console.log("Rate limited - retry after:", error.retryAfterInMs);
        break;
      default:
        console.error(`Cosmos error ${error.code}: ${error.message}`);
    }
  }
  throw error;
}

Optimistic Concurrency (ETags)

// Read with ETag
const { resource, etag } = await container
  .item("product-1", "electronics")
  .read<Product>();

if (resource && etag) {
  resource.price = 899.99;
  
  try {
    // Replace only if ETag matches
    await container.item("product-1", "electronics").replace(resource, {
      accessCondition: { type: "IfMatch", condition: etag },
    });
  } catch (error) {
    if (error instanceof ErrorResponse && error.code === 412) {
      console.log("Document was modified by another process");
    }
  }
}

TypeScript Types Reference

import {
  // Client & Resources
  CosmosClient,
  Database,
  Container,
  Item,
  Items,
  
  // Operations
  OperationInput,
  BulkOperationType,
  PatchOperation,
  
  // Queries
  SqlQuerySpec,
  SqlParameter,
  FeedOptions,
  
  // Partition Keys
  PartitionKeyDefinition,
  PartitionKeyDefinitionVersion,
  PartitionKeyKind,
  
  // Responses
  ItemResponse,
  FeedResponse,
  ResourceResponse,
  
  // Errors
  ErrorResponse,
} from "@azure/cosmos";

Best Practices

  1. Use Microsoft Entra Token Credential — Use DefaultAzureCredential for local development; use ManagedIdentityCredential or WorkloadIdentityCredential for production
  2. Always use parameterized queries — Prevents injection, improves plan caching
  3. Specify partition key — Avoid cross-partition queries when possible
  4. Use bulk operations — For multiple writes, use executeBulkOperations
  5. Handle 429 errors — Implement retry logic with exponential backoff
  6. Use ETags for concurrency — Prevent lost updates in concurrent scenarios
  7. Close client on shutdown — Call client.dispose() in cleanup

Common Patterns

Service Layer Pattern

export class ProductService {
  private container: Container;

  constructor(client: CosmosClient) {
    this.container = client
      .database(process.env.COSMOS_DATABASE!)
      .container(process.env.COSMOS_CONTAINER!);
  }

  async getById(id: string, category: string): Promise<Product | null> {
    try {
      const { resource } = await this.container
        .item(id, category)
        .read<Product>();
      return resource ?? null;
    } catch (error) {
      if (error instanceof ErrorResponse && error.code === 404) {
        return null;
      }
      throw error;
    }
  }

  async create(product: Omit<Product, "id">): Promise<Product> {
    const item = { ...product, id: crypto.randomUUID() };
    const { resource } = await this.container.items.create<Product>(item);
    return resource!;
  }

  async findByCategory(category: string): Promise<Product[]> {
    const querySpec: SqlQuerySpec = {
      query: "SELECT * FROM c WHERE c.partitionKey = @category",
      parameters: [{ name: "@category", value: category }],
    };
    const { resources } = await this.container.items
      .query<Product>(querySpec)
      .fetchAll();
    return resources;
  }
}

Related SDKs

SDKPurposeInstall
@azure/cosmosData plane (this SDK)npm install @azure/cosmos
@azure/arm-cosmosdbManagement plane (ARM)npm install @azure/arm-cosmosdb
@azure/identityAuthenticationnpm install @azure/identity

Больше skills от microsoft

oss-growth
microsoft
Персона OSS-хакера роста
agent-framework-azure-ai-py
microsoft
Создание агентов Azure AI Foundry с использованием Microsoft Agent Framework Python SDK (agent-framework-azure-ai). Используйте при создании постоянных агентов с AzureAIAgentsProvider, применении размещенных инструментов (интерпретатор кода, поиск файлов, веб-поиск), интеграции MCP-серверов, управлении потоками бесед или реализации потоковых ответов. Охватывает функциональные инструменты, структурированные выходные данные и агентов с несколькими инструментами.
development
airunway-aks-setup
microsoft
Set up AI Runway on AKS — from bare cluster to running model. Covers cluster verification, controller install, GPU assessment, provider setup, and first deployment. WHEN: "setup AI Runway", "onboard AKS cluster", "install AI Runway", "airunway setup", "deploy model to AKS", "GPU inference on AKS", "KAITO setup on AKS", "run LLM on AKS", "vLLM on AKS", "set up model serving on AKS", "AI Runway controller".
devops
appinsights-instrumentation
microsoft
Guidance for instrumenting webapps with Azure Application Insights. Provides telemetry patterns, SDK setup, and configuration references. WHEN: how to instrument app, App Insights SDK, telemetry patterns, what is App Insights, Application Insights guidance, instrumentation examples, APM best practices.
devops
applicationinsights-web-ts
microsoft
Инструментируйте браузерные/веб-приложения с помощью JavaScript SDK Application Insights (@microsoft/applicationinsights-web). Используйте для мониторинга реальных пользователей (RUM) — просмотры страниц, клики, зависимости AJAX/fetch, исключения, пользовательские события и трассировки агентов GenAI на стороне браузера, коррелируемые с бэкенд-трассировками OpenTelemetry. Охватывает скрипт загрузчика SDK и настройку npm, расширения фреймворков (React, React Native, Angular), Click Analytics, инициализаторы телеметрии и семантические конвенции OTel GenAI для спанов агента/инструмента/модели, генерируемых из браузера.
devops
azure-ai-anomalydetector-java
microsoft
Создавайте приложения для обнаружения аномалий с помощью Azure AI Anomaly Detector SDK для Java. Используйте при реализации одномерного/многомерного обнаружения аномалий, анализа временных рядов или мониторинга на основе ИИ.
development
azure-ai-language-conversations-py
microsoft
Реализация понимания разговорного языка (CLU) с использованием Python SDK azure-ai-language-conversations. Используйте при работе с ConversationAnalysisClient для анализа намерений и сущностей в разговоре, создании NLP-функций или интеграции языкового понимания в приложения.
development
azure-ai-ml-py
microsoft
Azure Machine Learning SDK v2 для Python. Используется для рабочих областей ML, заданий, моделей, наборов данных, вычислений и конвейеров. Триггеры: "azure-ai-ml", "MLClient", "workspace", "model registry", "training jobs", "datasets".
development