Azure Cosmos DB for NoSQL は、スキーマに依存しないドキュメント データベースです。 リレーショナル データベースとは異なり、Azure Cosmos DB には、Data API Builder (DAB) が自動的にイントロスペクトできる定義済みのスキーマはありません。 このガイドでは、GraphQL スキーマ ファイルを作成し、Azure Cosmos DB コンテナーと連携するように DAB を構成する方法について説明します。
前提条件
- 少なくとも 1 つのデータベースとコンテナーを持つ Azure Cosmos DB for NoSQL アカウント
- データ API ビルダー CLI。 CLI をインストールする
スキーマの要件を理解する
Azure Cosmos DB for NoSQL ではスキーマが強制されないため、DAB はデータから GraphQL 型を自動的に生成することはできません。 代わりに、次を定義する GraphQL スキーマ ファイルを指定する必要があります。
- コンテナーのドキュメント構造を表すオブジェクト型
- GRAPHQL 型を DAB 構成のエンティティ名にマップする
@modelディレクティブ - フィールド レベルのアクセスを特定のロールに制限する
@authorizeディレクティブ (省略可能)
次の例を使用してスキーマを手作りするか、 dab export コマンドを使用して既存の Cosmos DB データから生成できます。
GraphQL スキーマ ファイルを作成する
データ モデルを記述する .gql ファイルを作成します。 スキーマ ファイルでは、標準の GraphQL スキーマ定義言語 (SDL) と DAB のカスタム ディレクティブが使用されます。
基本的なスキーマの例
次の例では、ブック コンテナー内の共通フィールドを使用して Book 型を定義します。
type Book @model(name: "Book") {
id: ID
title: String
year: Int
pages: Int
Authors: [Author]
}
type Author @model(name: "Author") {
id: ID
firstName: String
lastName: String
}
Cosmos DB データからスキーマを生成する
コンテナーに既にデータがある場合は、それをサンプリングして開始スキーマを作成できます。 このコマンドは、推論された GraphQL スキーマ ファイルを、 -oで指定した出力ディレクトリに書き込みます。
dab export \
--graphql \
--generate \
-o ./schema-out
既定では、サンプリングでは TopNExtractorが使用されます。
サポートされているサンプリング モードは、 TopNExtractor、 EligibleDataSampler、および TimePartitionedSamplerです。
注
-o
/
--output パラメーターが必要です。 スキーマ ファイル名を指定しない場合、DAB は出力ディレクトリに schema.gql を生成します。
その他のモードとオプションについては、dab exportの CLI リファレンスを参照してください。
@model ディレクティブが必要です。 GraphQL 型は、DAB 構成ファイル内のエンティティ名にマップされます。
name パラメーターは、エンティティ名と正確に一致する必要があります。
注
Authors: [Author] フィールドは、別のコンテナーとのリレーションシップではなく、Book ドキュメント内の埋め込み配列を表します。 Azure Cosmos DB for NoSQL では、関連するデータを別のコンテナーに格納するのではなく、同じドキュメント内に埋め込む必要があります。
承認を含むスキーマ
特定のフィールドへのアクセスを制限するには、 @authorize ディレクティブを使用します。 このディレクティブは、フィールドにアクセスできるロールを指定する roles パラメーターを受け入れます。
type Book @model(name: "Book") {
id: ID
title: String @authorize(roles: ["authenticated", "metadataviewer"])
internalNotes: String @authorize(roles: ["editor"])
Authors: [Author]
}
この例は次のとおりです。
-
titleフィールドには、authenticatedロールまたはmetadataviewerロールを持つユーザーのみがアクセスできます -
internalNotesフィールドには、editorロールを持つユーザーのみがアクセスできます - エンティティ レベルのアクセス許可に基づいて、
@authorizeのないフィールドにアクセスできます
型レベルで @authorize を適用して、型全体へのアクセスを制限することもできます。
type InternalReport @model(name: "InternalReport") @authorize(roles: ["editor", "auditor"]) {
id: ID
title: String
confidentialData: String
}
Important
@authorize ディレクティブは、ランタイム構成で定義されたエンティティ レベルのアクセス許可に加えて機能します。 要求が成功するには、 @authorize ディレクティブとエンティティのアクセス許可の両方でアクセスを許可する必要があります。
たとえば、フィールドに @authorize(roles: ["editor"])があるが、エンティティに editor ロールのアクセス許可エントリがない場合、そのフィールドへのアクセスは拒否されます。
Warnung
@authorize(policy: "...") は、このスキーマ フローではサポートされていません。
@authorize(roles: [...]) を使用してください。
DAB ランタイムを構成する
スキーマ ファイルを作成したら、AZURE COSMOS DB アカウントで使用するように DAB を構成します。
構成を初期化する
dab init コマンドを使用して、Azure Cosmos DB の構成ファイルを作成します。
dab init \
--database-type cosmosdb_nosql \
--cosmosdb_nosql-database <your-database-name> \
--graphql-schema schema.gql \
--connection-string "<your-connection-string>"
<your-database-name>を Azure Cosmos DB データベース名に置き換え、<your-connection-string>を接続文字列に置き換えます。
必要に応じて、データ ソース構成に既定のコンテナーを設定する --cosmosdb_nosql-container <your-container-name> を含めます。
ヒント
運用環境では、接続文字列をハードコーディングするのではなく、環境変数を使用します。
dab init \
--database-type cosmosdb_nosql \
--cosmosdb_nosql-database <your-database-name> \
--graphql-schema schema.gql \
--connection-string "@env('COSMOSDB_CONNECTION_STRING')"
複数エンティティの追加
コンテナーに対応するエンティティを追加します。 エンティティ名は、スキーマ内の @model(name: "...") 値と一致する必要があります。
dab add Book \
--source Book \
--permissions "anonymous:read"
--source パラメーターは、<container-name>または<database-name>.<container-name>を受け取ります。 データベースとコンテナーの両方について明示的にする場合は、2 部構成の形式を使用します。
構成ファイルの例
初期化後、構成ファイルは次の例のようになります。
{
"$schema": "https://github.com/Azure/data-api-builder/releases/download/v1.2.11/dab.draft.schema.json",
"data-source": {
"database-type": "cosmosdb_nosql",
"options": {
"database": "Library",
"schema": "schema.gql"
},
"connection-string": "@env('COSMOSDB_CONNECTION_STRING')"
},
"entities": {
"Book": {
"source": "Book",
"permissions": [
{
"role": "anonymous",
"actions": ["read"]
},
{
"role": "metadataviewer",
"actions": ["read"]
}
]
}
}
}
注
構成ファイルの schema パスは、DAB 構成ファイルの場所を基準にしています。 GraphQL スキーマ ファイルが正しいディレクトリにあることを確認します。
この $schema URL は、特定の DAB リリースを指しています。 DAB バージョンに一致するスキーマ URL を使用します。
ロールベース・フィールドアクセス
ロールで @authorize ディレクティブを使用する場合は、ロールの割り当て方法を検討してください。
| シナリオ | ロールの割り当て |
@authorize フィールドへのアクセス |
|---|---|---|
| 匿名要求 | ロールが割り当てられていない | 拒否されました |
| 認証済み要求 |
authenticated システム ロールが自動的に割り当てられます |
ロールが一致する場合に許可 |
| カスタム ロール要求 | ロール名を持つ X-MS-API-ROLE ヘッダーを含める |
ロールが一致する場合に許可 |
このテーブルは、 @authorizeを明示的に含むフィールドまたは型に適用されます。
@authorizeを持たないフィールドの場合、エンティティ レベルのアクセス許可によってアクセスが決定されます。
カスタム ロールが必要な認証済み要求の場合は、 X-MS-API-ROLE ヘッダーを送信します。
GET /graphql HTTP/1.1
Host: localhost:5000
Authorization: Bearer <your-jwt-token>
X-MS-API-ROLE: metadataviewer
コンテナー間クエリ
コンテナー間の GraphQL 操作は、NoSQLのAzure Cosmos DBではサポートされていません。
dab addまたはdab updateを使用して異なるコンテナー内のエンティティ間のリレーションシップを構成しようとすると、CLI 検証は失敗します。
CLI エラー メッセージは次のとおりです。 Adding/updating Relationships is currently not supported in CosmosDB.
リレーションシップの構成の詳細 (他のデータベースでサポート) については、「 リレーションシップの構成」を参照してください。
コンテナー間の制限を越える
この制限を回避するには、1 つのコンテナー内で埋め込みドキュメントを使用するようにデータ モデルを再構築することを検討してください。 多くの場合、このアプローチは Azure Cosmos DB の方が効率的であり、NoSQL データ モデリングのベスト プラクティスに沿っています。
たとえば、リレーションシップを持つ個別の Book コンテナーと Author コンテナーの代わりに、
// Embedded model in a single container
{
"id": "book-1",
"title": "Introduction to DAB",
"authors": [
{
"firstName": "Jane",
"lastName": "Developer"
}
]
}
データ モデリング戦略の詳細については、「 Azure Cosmos DB でのデータ モデリング」を参照してください。
REST API の可用性
Azure Cosmos DB にはドキュメント操作用の包括的なネイティブ REST API が既に用意されているため、データ API ビルダーは Azure Cosmos DB for NoSQL の REST エンドポイントを生成しません。
Azure Cosmos DB for NoSQL で DAB を使用すると、DAB は GraphQL エンドポイントのみを公開し、OpenAPI を生成しません。 REST 経由でデータにアクセスするには、 Azure Cosmos DB REST API を直接使用します。
一般的な構成の問題
スキーマ ファイルが見つかりません
- エラー:
GraphQL schema file not found - 解決策: 構成の
schemaパスが構成ファイルの場所を基準にしていることを確認します。
エンティティ名の不一致
- エラー:
Entity '<name>' not found in schema - 解決策: 構成内のエンティティ名が
@model(name: "...")ディレクティブと正確に一致するかどうかを確認します。 名前は大文字と小文字が区別されます。
未承認のフィールド アクセス
- エラー: GraphQL 承認エラー (ロールが許可されていない場合など)
- 解決策:
@authorizeロールとエンティティのアクセス許可の両方で、要求元ロールへのアクセスが許可されていることを確認します。
次のステップ
関連するコンテンツ
- クイック スタート: NoSQL でデータ API ビルダーを使用する
- データ API ビルダーの機能の可用性
- Azure Cosmos DB におけるデータモデリング