次の方法で共有


エンティティリレーションシップ

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.entityBook定義します(この場合)。 つまり、構成ファイルに という 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を使用すると、更新されるエンティティから使用されるフィールド ()、およびターゲット エンティティ (SeriesBook) から使用されるフィールドを定義して、あるエンティティから他方のエンティティにデータを接続できます。

前のサンプルでは、エンティティのidSeriesデータベース フィールドがエンティティのデータベース フィールドseries_idBookと一致しています。

構成には、次の情報も含まれます。

"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 つのエンティティを視覚化できます。

著者、books_authors、書籍間の多対多関係を示す図。

表示されているように、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 エンティティとの間にリレーションシップをBookAuthor追加するには。 指定された構成では、DAB は次の例のように入れ子になったクエリを処理できます。

{
 authors {
    items {
      first_name
      last_name      
      books {
        items {
          book {
            id
            title
          }
          royalties_percentage
        }
      }      
    }
  }
}

あなたがすべての著者を返すように求めているところで、彼らが書いた本と関連するロイヤリティ。

リンク オブジェクトの使用

前のセクションで説明したプロセスは、多対多リレーションシップに関係するすべてのエンティティにGraphQL経由でアクセスする必要がある場合に最適です。 このシナリオは必ずしも当てはまるわけではありません。 たとえば、ロイヤリティを追跡する必要がない場合、 BookAuthor エンティティは実際にはエンド ユーザーに値を提供しません。 エンティティは、作成者に関連付けられた書籍にのみ使用されました。 リレーショナル データベースでは、多対多リレーションシップに参加しているテーブルを一緒に リンク する 3 番目のテーブルを使用して、多対多リレーションシップが作成されます。

著者、books_authors、書籍の間の別の多対多関係を示す図。

この図では、 という名前 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.fieldstarget.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_authorsAuthor使用して、エンティティとエンティティの間のBook多対多リレーションシップが定義されます。