azure-cosmos-ts – skill DevOps & Hạ tầng cho agent AI
SDK Azure Cosmos DB cho JavaScript/TypeScript (@azure/cosmos) cho các thao tác data plane. Dùng cho CRUD tài liệu, truy vấn, thao tác hàng loạt (bulk) và quản lý container.
Cài skill azure-cosmos-ts bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/azure-cosmos-ts-2f56f.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /azure-cosmos-ts – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/azure-cosmos-ts-2f56f.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $azure-cosmos-ts – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/azure-cosmos-ts-2f56f.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /azure-cosmos-ts – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/azure-cosmos-ts-2f56f.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /azure-cosmos-ts – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
@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/identityCurrent 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>Authentication
AAD with DefaultAzureCredential (Recommended)
import { CosmosClient } from "@azure/cosmos";
import { DefaultAzureCredential } from "@azure/identity";
const client = new CosmosClient({
endpoint: process.env.COSMOS_ENDPOINT!,
aadCredentials: new DefaultAzureCredential(),
});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)
└── ConflictsCore Operations
Confirm account/database/container, tenant-bound authorization and write/delete scope first. Partition keys are routing, not authorization. Bound query pages, RU cost, retries and runtime; fetchAll may be unbounded. Bulk operations are not an all-or-nothing transaction: inspect each response/error and retry only eligible failed items with idempotency/concurrency checks. Pin SDK versions and verify examples against [Microsoft SDK docs](https://learn.microsoft.com/en-us/javascript/api/overview/azure/cosmos-readme).
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) => {
const statusCode = result.response?.statusCode;
if (!result.error && statusCode !== undefined && statusCode >= 200 && statusCode < 300) {
console.log(`Operation ${index} succeeded`);
} else {
console.error(`Operation ${index} failed: ${statusCode ?? result.error?.code ?? "unknown"}`);
}
});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,
… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- azure-data-tables-py – SDK Azure Tables cho Python (Storage và Cosmos DB). Dùng cho lưu trữ key-value NoSQL…
- azure-devops – Thiết lập Azure Pipelines cho CI/CD, cấu hình pipeline build và release, quản lý dự án…
- azure-eventgrid-dotnet – SDK Azure Event Grid cho .NET. Thư viện client để xuất bản và tiêu thụ sự kiện với Azure…
- azure-eventgrid-java – Xây dựng ứng dụng hướng sự kiện bằng SDK Azure Event Grid cho Java. Dùng khi xuất bản sự…
- azure-eventgrid-py – SDK Azure Event Grid cho Python. Dùng để xuất bản sự kiện, xử lý CloudEvents và kiến…
- azure-eventhub-dotnet – SDK Azure Event Hubs cho .NET.
- azure-eventhub-py – SDK Azure Event Hubs cho Python để xử lý streaming. Dùng cho nhập sự kiện thông lượng…
- azure-eventhub-ts – Xử lý streaming sự kiện thông lượng cao và nhập dữ liệu thời gian thực.