エンティティリレーションシップ
GraphQLクエリでは、関連するオブジェクトとそのフィールドを走査できるため、1 つのクエリだけで次のような記述を行うことができます。
{
books
{
items {
id
title
authors {
items {
first_name
last_name
}
}
}
}
}
書籍とその著者を取得する。
この機能を機能させるには、データ API ビルダーが 2 つのオブジェクトが相互にどのように関連しているかを把握する必要があります。 構成ファイルの セクションには relationships
、この機能を正しく効率的に動作させるための必要なメタデータが用意されています。
リレーションシップの構成
データ API ビルダーで使用しているデータベースに関係なく、オブジェクトが別のデータベースに関連していることを Data API ビルダーに明示的に伝える必要があります。 2 つのエンティティ間で確立できるリレーションシップには、次の 3 種類があります。
一対多リレーションシップ
一対多リレーションシップを使用すると、オブジェクトは関連オブジェクトの一覧にアクセスできます。 たとえば、書籍シリーズでは、そのシリーズのすべての書籍にアクセスできます。
{
series {
items {
name
books {
items {
title
}
}
}
}
}
基になる 2 つのデータベース オブジェクト間のリレーションシップをサポートする外部キーがある場合は、データ API ビルダーに、このようなリレーションシップを公開するように指示するだけで済みます。 DAB CLI を使用する場合:
dab update Series --relationship books --target.entity Book --cardinality many
次の例で使用されるエンティティを series
更新します。
"Series": {
"source": "dbo.series",
...
"relationships": {
"books": {
"target.entity": "Book",
"cardinality": "many"
}
}
...
}
要素の下に新しいキーがrelationships
追加されます。 books
要素は、オブジェクトから series
で定義されているオブジェクトに移動するためにGraphQL フィールドに使用される名前をtarget.entity
Book
定義します(この場合)。 つまり、構成ファイルに という Book
エンティティが必要です。
プロパティはcardinality
、各系列に多数の書籍が存在する可能性があることを Data API ビルダーに指示するため、作成されたGraphQL フィールドは項目の一覧を返します。
そのプロパティは必要なすべてです。 起動時に、Data API ビルダーは、定義されたリレーションシップを維持するために使用する必要があるデータベース フィールドを自動的に検出します。
データベースリレーションシップを維持する外部キー制約がない場合、データ API ビルダーは使用されているフィールドを自動的に把握できません。 2 つのエンティティを関連付けるフィールドを Data API ビルダーに指示するには、それらを手動で指定する必要があります。 CLI では、 を使用して dab update
指定できます。
dab update Series --relationship books --target.entity Book --cardinality many --relationship.fields "id:series_id"
オプションrelationship.fields
を使用すると、更新されるエンティティから使用されるフィールド ()、およびターゲット エンティティ (Series
Book
) から使用されるフィールドを定義して、あるエンティティから他方のエンティティにデータを接続できます。
前のサンプルでは、エンティティのid
Series
データベース フィールドがエンティティのデータベース フィールドseries_id
Book
と一致しています。
構成には、次の情報も含まれます。
"Series": {
"source": "dbo.series",
...
"relationships": {
"books": {
"cardinality": "many",
"target.entity": "Book",
"source.fields": ["id"],
"target.fields": ["series_id"]
}
}
...
}
多対一リレーションシップ
多対一リレーションシップは、2 つの大きな違いがある一対多リレーションシップに似ています。
- が
cardinality
に設定されているone
- 作成されたGraphQL フィールドはリストではなくスカラーを返します
前に使用した書籍シリーズのサンプルに従って、書籍は 1 つのシリーズに含めることができるため、次の DAB CLI コマンドを使用してリレーションシップが作成されます。
dab update Book --relationship series --target.entity Series --cardinality one
これにより、次の構成が生成されます。
"Book": {
"source": "dbo.books",
...
"relationships": {
"series": {
"target.entity": "Series",
"cardinality": "one"
}
}
}
これにより、次の例のようなGraphQLクエリが許可されます。
{
books {
items {
id
title
series {
name
}
}
}
}
各本は、それが属しているシリーズも返す場所。
多対多リレーションシップ
多対多のリレーションシップは、一対多リレーションシップと多対一リレーションシップのペアと見なすことができます。 1 人の著者は、複数の書籍 (一対多リレーションシップ) を確実に書くことができますが、複数の著者が同じ書籍 (多対一リレーションシップ) で作業できることも事実です。
データ API ビルダーでは、次の種類のリレーションシップがネイティブでサポートされています。
- 一対多/多対一リレーションシップのペアを使用する。
- リンク オブジェクトの使用。
一対多/多対一リレーションシップのペアを使用する
あるビジネス要件の 1 つは、書籍の作成者間でロイヤリティがどのように分割されるかを追跡する必要があります。 このような要件を実装するには、著者を結び付ける専用エンティティ、書籍、および割り当てられたロイヤリティが必要です。 そのため、次の 3 つのエンティティが必要です。
authors
作成者の経歴の詳細を表す 。books
タイトルや国際標準書籍番号 (ISBN) などの書籍データを表します。books_authors
書籍とその著者の両方に関連するデータを表す場合は 、たとえば、作成者が特定の書籍に対して取得するロイヤリティの割合などです。
次の図では、3 つのエンティティを視覚化できます。
表示されているように、2 つの双方向リレーションシップがあります。
- と の間
authors
の一対多/多対一リレーションシップbooks_authors
- と の間
books
の一対多/多対一リレーションシップbooks_authors
DAB でこのようなシナリオを適切に処理するために必要なのは、関連するエンティティとマッピングを構成ファイルに作成することです。 エンティティと Author
エンティティが構成ファイルに既に存在すると仮定しますBook
。
dab add BookAuthor --source dbo.books_authors --permissions "anonymous:*"
新しいエンティティを追加するには、 を実行 dab update
します。
dab update Book --relationship authors --target.entity BookAuthor --cardinality many --relationship.fields "id:book_id"
dab update Author --relationship books --target.entity BookAuthor --cardinality many --relationship.fields "id:author_id"
新しく作成 BookAuthor
したエンティティにリレーションシップを追加するには、次を再度実行 dab update
します。
dab update BookAuthor --relationship book --target.entity Book --cardinality one --relationship.fields "book_id:id"
dab update BookAuthor --relationship author --target.entity Author --cardinality one --relationship.fields "author_id:id"
エンティティと BookAuthor
エンティティとの間にリレーションシップをBook
Author
追加するには。 指定された構成では、DAB は次の例のように入れ子になったクエリを処理できます。
{
authors {
items {
first_name
last_name
books {
items {
book {
id
title
}
royalties_percentage
}
}
}
}
}
あなたがすべての著者を返すように求めているところで、彼らが書いた本と関連するロイヤリティ。
リンク オブジェクトの使用
前のセクションで説明したプロセスは、多対多リレーションシップに関係するすべてのエンティティにGraphQL経由でアクセスする必要がある場合に最適です。 このシナリオは必ずしも当てはまるわけではありません。 たとえば、ロイヤリティを追跡する必要がない場合、 BookAuthor
エンティティは実際にはエンド ユーザーに値を提供しません。 エンティティは、作成者に関連付けられた書籍にのみ使用されました。 リレーショナル データベースでは、多対多リレーションシップに参加しているテーブルを一緒に リンク する 3 番目のテーブルを使用して、多対多リレーションシップが作成されます。
この図では、 という名前 books_authors
のテーブルが存在し、作成者を書籍や書籍と著者とリンクしていることがわかります。 このリンク テーブルをエンド ユーザーに公開する必要はありません。 リンク テーブルは、多対多リレーションシップを存在させる成果物にすぎませんが、データ API ビルダーは、適切に使用するためにその存在を認識する必要があります。
DAB CLI を使用して、多対多リレーションシップを作成し、リンク オブジェクトを構成することもできます (前のセクションで作成したすべてのリレーションシップを削除し、それらの間にリレーションシップが既に構成されていない と Author
エンティティでのみBook
開始してください)。
dab update Book --relationship authors --target.entity Author --cardinality many --relationship.fields "id:id" --linking.object "dbo.books_authors" --linking.source.fields "book_id" --linking.target.fields "author_id"
次の例のように JSON 構成ファイルが更新されます。
"Book": {
"source": "dbo.books",
...
"relationships": {
"authors": {
"cardinality": "many",
"target.entity": "author",
"source.fields": [ "id" ],
"target.fields": [ "id" ],
"linking.object": "dbo.books_authors",
"linking.source.fields": [ "book_id" ],
"linking.target.fields": [ "author_id" ]
}
}
}
この構成では、書籍の作成者へのアクセスを authors
許可するフィールドを Book
エンティティに追加することを DAB に指示しています。 authors
を にmany
できます。そのため、GraphQL クエリがフィールドにアクセスすると、作成者の一覧がauthors
返されます。 このリレーションシップは、書籍から作成者への移動方法を定義します。書籍から作成者への移動に使用されるデータベース フィールドは、この記事でsource.fields
target.fields
前述した一対多リレーションシップまたは多対一リレーションシップと同様に、書籍の と著者の で定義されます。
このリレーションシップは多対多リレーションシップであるため、2 つのエンティティ間に直接接続がないため、 を linking.object
使用する必要があります。 このサンプルでは、データベース テーブル dbo.books_authors
がリンク オブジェクトとして使用されています。 リンク オブジェクトが書籍を作成者に接続する方法は、 プロパティと linking.target.fields
プロパティでlinking.source.fields
定義されます。 最初の 1 つは、ソース エンティティ ( Book
) が好みのオブジェクトにどのように接続されているかを DAB に伝え、2 つ目はリンク オブジェクトがターゲット エンティティ Author
にどのように接続されているかをサンプルで示します。
提供された情報の使用方法を理解するために、次の同等のクエリの例を使用できます。
select *
from dbo.books as b
inner join dbo.books_authors as ba on b.id = ba.book_id
inner join dbo.authors a on ba.author_id = a.id
指定された構成では、DAB は次の例のようなGraphQLを理解できます。
{
books {
items {
id
title
authors {
items {
first_name
last_name
}
}
}
}
}
書籍とその作成者を取得する場所。
から Author
へのナビゲーションを Book
許可するには、同じ原則を適用し、次のコマンドを使用して構成を更新します。
dab update Author --relationship books --target.entity Book --cardinality many --relationship.fields "id:id" --linking.object "dbo.books_authors" --linking.source.fields "author_id" --linking.target.fields "book_id"
これにより、背後にあるリンク オブジェクトdbo.books_authors
をAuthor
使用して、エンティティとエンティティの間のBook
多対多リレーションシップが定義されます。