JavaScript용 Azure Cosmos DB 클라이언트 라이브러리 - 버전 4.0.0
/TypeScript
Azure Cosmos DB는 문서, 키-값, 넓은 열 및 그래프 데이터베이스를 지원하는 전세계로 분산된 다중 모델 데이터베이스 서비스입니다. 이 패키지는 JavaScript/TypeScript 애플리케이션이 SQL API 데이터베이스 및 포함된 JSON 문서와 상호 작용하기 위한 것입니다.
- Cosmos DB 데이터베이스 만들기 및 설정 수정
- JSON 문서의 컬렉션을 저장하도록 컨테이너 만들기 및 수정
- 컨테이너에서 항목(JSON 문서) 만들기, 읽기, 업데이트, 삭제
- SQL 유사 구문을 사용하여 데이터베이스의 문서 쿼리
주요 링크:
시작
필수 조건
Azure 구독 및 Cosmos DB SQL API 계정
이 패키지를 사용하려면 Azure 구독과 Cosmos DB 계정(SQL API)이 있어야 합니다.
Cosmos DB SQL API 계정이 필요한 경우 Azure Cloud Shell을 사용하여 다음 Azure CLI 명령을 통해 만들 수 있습니다.
az cosmosdb create --resource-group <resource-group-name> --name <cosmos-database-account-name>
또는 Azure Portal에서 계정을 만들 수 있습니다.
NodeJS
이 패키지는 NodeJS와 함께 미리 설치된 npm을 통해 배포됩니다. Node v10 이상을 사용해야 합니다.
CORS
브라우저용으로 개발해야 하는 경우 Cosmos DB 계정에 대해 CORS(원본 간 리소스 공유) 규칙을 설정해야 합니다. 연결된 문서의 지침에 따라 Cosmos DB에 대한 새 CORS 규칙을 만듭니다.
이 패키지 설치
npm install @azure/cosmos
계정 자격 증명 가져오기
Cosmos DB 계정 엔드포인트 및 키가 필요합니다. Azure Portal에서 찾거나 아래의 Azure CLI 코드 조각을 사용할 수 있습니다. 조각은 Bash 셸에 대해 서식이 지정됩니다.
az cosmosdb show --resource-group <your-resource-group> --name <your-account-name> --query documentEndpoint --output tsv
az cosmosdb keys list --resource-group <your-resource-group> --name <your-account-name> --query primaryMasterKey --output tsv
CosmosClient
의 인스턴스 만들기
Cosmos DB와의 상호 작용은 CosmosClient 클래스의 인스턴스로 시작됩니다.
const { CosmosClient } = require("@azure/cosmos");
const endpoint = "https://your-account.documents.azure.com";
const key = "<database account masterkey>";
const client = new CosmosClient({ endpoint, key });
async function main() {
// The rest of the README samples are designed to be pasted into this function body
}
main().catch((error) => {
console.error(error);
});
간단히 하기 위해 코드에 key
및 endpoint
가 직접 포함되었지만 dotenv와 같은 프로젝트를 사용하거나 환경 변수에서 로드하는 등 소스 제어에 없는 파일에서 로드하려고 할 수 있습니다.
프로덕션 환경에서 키와 같은 비밀은 Azure Key Vault에 저장해야 합니다.
주요 개념
CosmosClient를 초기화한 후에는 Cosmos DB의 기본 리소스 종류와 상호 작용할 수 있습니다.
데이터베이스: Cosmos DB 계정은 여러 데이터베이스를 포함할 수 있습니다. 데이터베이스를 만드는 경우 문서와 상호 작용할 때 사용할 API를 지정합니다. SQL, MongoDB, Gremlin, Cassandra 또는 Azure Table. 데이터베이스 개체를 사용하여 컨테이너를 관리합니다.
컨테이너: 컨테이너는 JSON 문서의 컬렉션입니다. 컨테이너 개체의 메서드를 사용하여 컨테이너에서 항목을 만들고(삽입), 읽기, 업데이트, 삭제합니다.
항목: 항목은 컨테이너에 저장된 JSON 문서입니다. 각 항목에는 컨테이너 내에서 항목을 고유하게 식별하는 값이 있는
id
키가 포함되어야 합니다.id
를 제공하지 않으면 SDK가 자동으로 생성합니다.
이러한 리소스에 대한 자세한 내용은 Azure Cosmos 데이터베이스, 컨테이너, 항목 작업을 참조하세요.
예제
다음 섹션에서는 다음을 비롯한 가장 일반적인 Cosmos DB 작업 몇 가지에 대한 여러 코드 조각을 제공합니다.
데이터베이스 만들기
CosmosClient를 인증한 후 계정의 모든 리소스로 작업할 수 있습니다. 아래 코드 조각은 NOSQL API 데이터베이스를 만듭니다.
const { database } = await client.databases.createIfNotExists({ id: "Test Database" });
console.log(database.id);
컨테이너 만들기
이 예제에서는 기본 설정을 사용하여 컨테이너를 만듭니다.
const { container } = await database.containers.createIfNotExists({ id: "Test Database" });
console.log(container.id);
파티션 키 사용
이 예제에서는 지원되는 다양한 유형의 파티션 키를 보여줍니다.
await container.item("id", "1").read(); // string type
await container.item("id", 2).read(); // number type
await container.item("id", true).read(); // boolean type
await container.item("id", {}).read(); // None type
await container.item("id", undefined).read(); // None type
await container.item("id", null).read(); // null type
파티션 키가 단일 값으로 구성된 경우 리터럴 값 또는 배열로 제공할 수 있습니다.
await container.item("id", "1").read();
await container.item("id", ["1"]).read();
파티션 키가 둘 이상의 값으로 구성된 경우 배열로 제공해야 합니다.
await container.item("id", ["a", "b"]).read();
await container.item("id", ["a", 2]).read();
await container.item("id", [{}, {}]).read();
await container.item("id", ["a", {}]).read();
await container.item("id", [2, null]).read();
항목 삽입
컨테이너에 항목을 삽입하려면 데이터가 포함된 개체를 Items.upsert에 전달합니다. Azure Cosmos DB 서비스에는 각 항목 id
에 키가 있어야 합니다. id
를 제공하지 않으면 SDK가 자동으로 생성합니다.
다음은 컨테이너에 여러 항목을 삽입하는 예제입니다.
const cities = [
{ id: "1", name: "Olympia", state: "WA", isCapitol: true },
{ id: "2", name: "Redmond", state: "WA", isCapitol: false },
{ id: "3", name: "Chicago", state: "IL", isCapitol: false }
];
for (const city of cities) {
await container.items.create(city);
}
항목 읽기
컨테이너에서 단일 항목을 읽으려면 Item.read를 사용합니다. 이는 SQL을 사용하여 id
로 쿼리하는 것보다 비용이 적게 드는 작업입니다.
await container.item("1", "1").read();
계층적 파티션 키가 있는 컨테이너의 CRUD
계층적 파티션 키를 사용하여 컨테이너 만들기
const containerDefinition = {
id: "Test Database",
partitionKey: {
paths: ["/name", "/address/zip"],
version: PartitionKeyDefinitionVersion.V2,
kind: PartitionKeyKind.MultiHash,
},
}
const { container } = await database.containers.createIfNotExists(containerDefinition);
console.log(container.id);
계층적 파티션 키가 로 정의된 항목을 삽입합니다. ["/name", "/address/zip"]
const item = {
id: 1,
name: 'foo',
address: {
zip: 100
},
active: true
}
await container.items.create(item);
계층적 파티션 키가 로 정의된 컨테이너에서 단일 항목을 읽으려면 ["/name", "/address/zip"],
await container.item("1", ["foo", 100]).read();
계층적 파티션 키가 로 정의된 계층적 파티션 키를 사용하여 항목을 쿼리합니다. ["/name", "/address/zip"],
const { resources } = await container.items
.query("SELECT * from c WHERE c.active = true", {
partitionKey: ["foo", 100],
})
.fetchAll();
for (const item of resources) {
console.log(`${item.name}, ${item.address.zip} `);
}
항목 삭제
컨테이너에서 항목을 삭제하려면 Item.delete를 사용합니다.
// Delete the first item returned by the query above
await container.item("1").delete();
데이터베이스 쿼리
Cosmos DB SQL API 데이터베이스는 SQL 유사 구문을 사용하여 Items.query로 컨테이너의 항목 쿼리를 지원합니다.
const { resources } = await container.items
.query("SELECT * from c WHERE c.isCapitol = true")
.fetchAll();
for (const city of resources) {
console.log(`${city.name}, ${city.state} is a capitol `);
}
매개 변수 및 해당 값이 포함된 개체를 Items.query에 전달하여 매개 변수화된 쿼리를 수행합니다.
const { resources } = await container.items
.query({
query: "SELECT * from c WHERE c.isCapitol = @isCapitol",
parameters: [{ name: "@isCapitol", value: true }]
})
.fetchAll();
for (const city of resources) {
console.log(`${city.name}, ${city.state} is a capitol `);
}
SQL API를 사용하여 Cosmos DB 데이터베이스를 쿼리하는 방법에 대한 자세한 내용은 SQL 쿼리를 사용하여 Azure Cosmos DB 데이터 쿼리를 참조하세요.
변경 피드 끌어오기 모델
파티션 키, 피드 범위 또는 전체 컨테이너에 대해 변경 피드를 가져올 수 있습니다.
변경 피드를 처리하려면 의 ChangeFeedPullModelIterator
instance 만듭니다. 를 처음 만들 ChangeFeedPullModelIterator
때 변경 내용을 읽을 시작 위치와 변경 내용을 가져올 리소스(파티션 키 또는 FeedRange)로 구성된 에 ChangeFeedIteratorOptions
필요한 changeFeedStartFrom
값을 지정해야 합니다. 필요에 따라 를 ChangeFeedIteratorOptions
사용하여 maxItemCount
페이지당 받은 최대 항목 수를 설정할 수 있습니다.
참고: 값을 지정하지 changeFeedStartFrom
않으면 Now()에서 전체 컨테이너에 대해 changefeed가 페치됩니다.
변경 피드에는 네 가지 시작 위치가 있습니다.
Beginning
// Signals the iterator to read changefeed from the beginning of time.
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Beginning();
}
const iterator = container.getChangeFeedIterator(options);
Time
// Signals the iterator to read changefeed from a particular point of time.
const time = new Date("2023/09/11") // some sample date
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Time(time);
}
Now
// Signals the iterator to read changefeed from this moment onward.
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Now();
}
Continuation
// Signals the iterator to read changefeed from a saved point.
const continuationToken = "some continuation token recieved from previous request";
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Continuation(continuationToken);
}
파티션 키에 대한 변경 피드를 가져오는 예제는 다음과 같습니다.
const partitionKey = "some-partition-Key-value";
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Beginning(partitionKey),
};
const iterator = container.items.getChangeFeedIterator(options);
while (iterator.hasMoreResults) {
const response = await iterator.readNext();
// process this response
}
변경 피드는 사실상 이후의 모든 쓰기 및 업데이트를 포함하는 항목의 무한 목록이므로 의 hasMoreResults
값은 항상 true
입니다. 변경 피드를 읽으려고 하고 사용할 수 있는 새 변경 내용이 없으면 상태 응답을 NotModified
받게 됩니다.
자세한 사용 지침 및 변경 피드 예제는 여기에서 찾을 수 있습니다.
오류 처리
SDK는 작업 중에 발생할 수 있는 다양한 유형의 오류를 생성합니다.
ErrorResponse
는 작업의 응답이 =400의 >오류 코드를 반환하는 경우 throw됩니다.TimeoutError
는 시간 제한으로 인해 Abort가 내부적으로 호출되는 경우 throw됩니다.AbortError
사용자가 전달한 신호로 인해 중단이 발생한 경우 이 throw됩니다.RestError
네트워크 문제로 인해 기본 시스템 호출이 실패할 경우 throw됩니다.- devDependencies에서 생성된 오류입니다. 예를 들어.
@azure/identity
패키지는 을 throwCredentialUnavailableError
할 수 있습니다.
다음은 , , TimeoutError
AbortError
및 RestError
형식ErrorResponse
의 오류를 처리하는 예제입니다.
try {
// some code
} catch (err) {
if (err instanceof ErrorResponse) {
// some specific error handling.
} else if (err instanceof RestError) {
// some specific error handling.
}
// handle other type of errors in similar way.
else {
// for any other error.
}
}
이러한 오류를 적절하게 처리하여 애플리케이션이 오류로부터 정상적으로 복구하고 예상대로 계속 작동할 수 있도록 하는 것이 중요합니다. 이러한 오류 및 가능한 해결 방법에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
문제 해결
일반
서비스에서 반환된 Cosmos DB 오류와 상호 작용할 때 REST API 요청에 대해 반환된 것과 동일한 HTTP 상태 코드에 해당합니다.
Azure Cosmos DB에 대한 HTTP 상태 코드
충돌
예를 들어 Cosmos DB 데이터베이스에서 이미 사용 중인 id
를 사용하여 항목을 만들려고 하면 충돌을 나타내는 409
오류가 반환됩니다. 다음 코드 조각에서 오류는 예외를 catch하고 오류에 대한 추가 정보를 표시하여 적절히 처리됩니다.
try {
await containers.items.create({ id: "existing-item-id" });
} catch (error) {
if (error.code === 409) {
console.log("There was a conflict with an existing item");
}
}
트랜스파일링
Azure SDK는 ES5 JavaScript 구문 및 LTS 버전의 Node.js를 지원하도록 설계되었습니다. Internet Explorer 또는 노드 6과 같은 이전 JavaScript 런타임에 대한 지원이 필요한 경우 빌드 프로세스의 일부로 SDK 코드를 트랜스파일링해야 합니다.
재시도를 통한 일시적인 오류 처리
Cosmos DB를 사용하는 동안 서비스에 적용된 요금 제한에 의한 일시적인 오류나 네트워크 중단과 같은 다른 일시적인 문제가 발생할 수 있습니다. 이러한 유형의 오류를 처리하는 방법에 대한 내용은 클라우드 디자인 패턴 가이드의 다시 시도 패턴 및 관련 회로 차단기 패턴을 참조하세요.
로깅
로깅을 사용하도록 설정하면 실패에 대한 유용한 정보를 파악하는 데 도움이 될 수 있습니다. HTTP 요청 및 응답 로그를 보려면 AZURE_LOG_LEVEL
환경 변수를 info
로 설정합니다. 또는 에서 를 호출 setLogLevel
하여 런타임에 로깅을 @azure/logger
사용하도록 설정할 수 있습니다. 를 사용하는 AZURE_LOG_LEVEL
동안 로깅 라이브러리가 초기화되기 전에 설정해야 합니다.
라이브러리를 사용하는 dotenv
경우 라이브러리를 로깅하기 전에 이러한 라이브러리가 초기화되었는지 확인하는 것이 좋습니다.
const { setLogLevel } = require("@azure/logger");
setLogLevel("info");
로그를 사용하는 방법에 대한 자세한 내용은 @azure/logger package docs를 참조하세요.
진단
Cosmos 진단 기능은 모든 클라이언트 작업에 대한 향상된 인사이트를 제공합니다. CosmosDiagnostics 개체가 모든 클라이언트 작업의 응답에 추가됩니다. 예:
- 지점 조회 작업 리포지토리 -
item.read()
, ,container.create()
database.delete()
- 쿼리 작업 리포지토리 -
queryIterator.fetchAll()
, - 대량 및 일괄 처리 작업 -
item.batch()
. - 오류/예외 응답 개체입니다.
CosmosDiagnostics 개체가 모든 클라이언트 작업의 응답에 추가됩니다. Cosmos 진단 수준, 정보, 디버그 및 디버그 안전하지 않은 3가지가 있습니다. 프로덕션 시스템에 대한 정보만을 의미하며 디버그 및 디버그 안전하지 않은 정보는 훨씬 더 높은 리소스를 소비하므로 개발 및 디버깅 중에 사용됩니다. Cosmos 진단 수준은 2가지 방법으로 설정할 수 있습니다.
- 프로그래밍 방식으로
const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
- 환경 변수 사용. (환경 변수에 의해 설정된 진단 수준은 클라이언트 옵션을 통해 설정하는 것보다 우선 순위가 높습니다.)
export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"
Cosmos Diagnostic에는 3개의 멤버가 있습니다.
ClientSideRequestStatistics 유형: 메타데이터 조회, 다시 시도, 연결한 엔드포인트, 페이로드 크기 및 기간과 같은 요청 및 응답 통계를 포함한 집계 진단 세부 정보를 포함합니다. (항상 수집되며 프로덕션 시스템에서 사용할 수 있습니다.)
DiagnosticNode: 자세한 진단 정보를 캡처하는 트리와 유사한 구조체입니다. 브라우저에
har
있는 기록과 유사합니다. 이 기능은 기본적으로 사용하지 않도록 설정되며 비프로덕션 환경만 디버깅하기 위한 것입니다. (진단 수준 디버그 및 디버그 안전하지 않음에서 수집됨)ClientConfig: 클라이언트를 초기화하는 동안 클라이언트의 구성 설정과 관련된 필수 정보를 캡처합니다. (진단 수준 디버그 및 디버그 안전하지 않음에서 수집됨)
이 수준은 CosmosDiagnostics
요청 및 응답 페이로드를 debug-unsafe
캡처하고 로그하도록 선택하는 경우(기본적으로 수준에서 로깅 @azure/loggerverbose
됨) 프로덕션 환경에서 진단 수준을 로 설정하지 않도록 합니다. 이러한 페이로드는 로그 싱크에서 캡처될 수 있습니다.
진단 사용
- 는
diagnostics
모든 Response 개체에 추가됩니다. 다음과 같이 프로그래밍 방식으로 액세스할CosmosDiagnostic
수 있습니다.
// For point look up operations
const { container, diagnostics: containerCreateDiagnostic } =
await database.containers.createIfNotExists({
id: containerId,
partitionKey: {
paths: ["/key1"],
},
});
// For Batch operations
const operations: OperationInput[] = [
{
operationType: BulkOperationType.Create,
resourceBody: { id: 'A', key: "A", school: "high" },
},
];
const response = await container.items.batch(operations, "A");
// For query operations
const queryIterator = container.items.query("select * from c");
const { resources, diagnostics } = await queryIterator.fetchAll();
// While error handling
try {
// Some operation that might fail
} catch (err) {
const diagnostics = err.diagnostics
}
- 를 사용하여
@azure/logger
로깅diagnostics
할 수도 있습니다. 진단은 항상 수준에서verbose
를 사용하여@azure/logger
기록됩니다. 따라서 진단 수준을 또는debug-unsafe
@azure/logger
로debug
설정하고 수준을 로verbose
diagnostics
설정하면 로 기록됩니다.
다음 단계
추가 샘플 코드
SDK의 GitHub 리포지토리에서 여러 샘플을 사용할 수 있습니다. 이러한 샘플에는 Cosmos DB를 사용하는 동안 흔히 발생하는 추가 시나리오에 대한 예제 코드가 들어 있습니다.
- 데이터베이스 작업
- 컨테이너 작업
- 항목 작업
- 인덱싱 구성
- 컨테이너 변경 피드 읽기
- 저장 프로시저
- 데이터베이스/컨테이너 처리량 설정 변경
- 다중 지역 쓰기 작업
제한 사항
현재 아래 기능은 지원되지 않습니다. 대체 옵션의 경우 아래 해결 방법 섹션을 검사.
데이터 평면 제한 사항:
- DISTINCT 하위 쿼리의 COUNT가 있는 쿼리
- 직접 TCP 모드 액세스
- 정렬, 계산 및 고유와 같은 파티션 간 쿼리 집계는 연속 토큰을 지원하지 않습니다. SELECT * FROM과 같은 스트리밍 가능한 쿼리 WHERE , 연속 토큰을 지원합니다. 연속 토큰 없이 스트리밍할 수 없는 쿼리를 실행하려면 "해결 방법" 섹션을 참조하세요.
- 변경 피드: 프로세서
- 변경 피드: 여러 파티션 키 값 읽기
- 변경 피드 끌어오기 모델 모든 버전 및 삭제 모드 #27058
- 부분 계층적 파티션 키에 대한 변경 피드 끌어오기 모델 지원 #27059
- 혼합 형식에 대한 파티션 간 ORDER BY
- CollectionSizeUsage, DatabaseUsage 및 DocumentUsage 메트릭 가져오기
- 지리 공간적 인덱스 만들기
- 자동 크기 조정 처리량 업데이트
컨트롤 플레인 제한 사항:
해결 방법
파티션 간 쿼리에 대한 연속 토큰
사이드카 패턴을 사용하여 연속 토큰 지원을 통해 파티션 간 쿼리를 수행할 수 있습니다. 이 패턴을 사용하면 애플리케이션을 서로 다른 유형의 구성 요소 및 기술로 구성할 수도 있습니다.
비스트림할 수 있는 파티션 간 쿼리 실행
연속 토큰을 사용하지 않고 스트리밍할 수 없는 쿼리를 실행하려면 필요한 쿼리 사양 및 옵션을 사용하여 쿼리 반복기를 만들 수 있습니다. 다음 샘플 코드는 쿼리 반복기를 사용하여 연속 토큰 없이 모든 결과를 가져오는 방법을 보여 줍니다.
const querySpec = {
query: "SELECT * FROM c WHERE c.status = @status",
parameters: [{ name: "@status", value: "active" }],
};
const queryOptions = {
maxItemCount: 10, // maximum number of items to return per page
enableCrossPartitionQuery: true,
};
const querIterator = await container.items.query(querySpec, queryOptions);
while (querIterator.hasMoreResults()) {
const { resources: result } = await querIterator.fetchNext();
//Do something with result
}
이 방법은 스트리밍 가능한 쿼리에도 사용할 수 있습니다.
컨트롤 플레인 작업
일반적으로 지원되지 않는 컨트롤 플레인 제한 사항에 대해 Azure Portal, Azure Cosmos DB 리소스 공급자 REST API, Azure CLI 또는 PowerShell 을 사용할 수 있습니다.
추가 설명서
Cosmos DB 서비스에 대한 보다 광범위한 설명서는 docs.microsoft.com에 있는 Azure Cosmos DB 문서를 참조하세요.
유용한 링크
- Azure Cosmos DB 시작
- 빠른 시작
- 자습서
- 샘플
- Azure Cosmos DB 서비스의 리소스 모델 소개
- Azure Cosmos DB 서비스의 SQL API 소개
- 분할
- API 문서
참여
이 라이브러리에 기여하려면 기여 가이드 를 참조하여 코드를 빌드하고 테스트하는 방법에 대해 자세히 알아보세요.
Azure SDK for JavaScript