Data API 建構器中的實體關係

實體關係允許 GraphQL 查詢遍歷相關實體,使得以單一查詢即可處理複雜的資料形狀。 例如:

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

為了達成此行為,必須透過設定檔中的relationships 区块 告知 DAB 實體之間的關聯。

Configuration

為了定義實體之間的關係:

  • 在實體設定中使用物件 relationships
  • 請提供 target.entity 名稱。
  • 設定 cardinality"one""many"
  • 可選擇性地指定 source.fieldstarget.fields
  • linking.object用於建模多對多關係且不暴露連接表時。

CLI 範例

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"

設定範例

"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" ]
    }
  }
}

一對多

  • 使用基數 "many"
  • 範例:Series 有許多 Books
  • DAB 可以在外鍵存在的情況下推斷欄位。
dab update Series \
  --relationship books \
  --target.entity Book \
  --cardinality many

多對一

  • 使用基數 "one"
  • 範例:A Book 屬於一個 Series
dab update Book \
  --relationship series \
  --target.entity Series \
  --cardinality one

多對多(連結物件)

  • 使用一個在 GraphQL 中未公開的聯結表。
  • 透過連接表定義從來源到目標的連結欄位。
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"

多對多(顯式連接實體)

  • 將 join 表公開作為 GraphQL 物件。
  • 定義三個實體的關係。
dab add BookAuthor \
  --source dbo.books_authors \
  --permissions "anonymous:*"

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 和 從 AuthorBook),需要在目標實體上定義第二個關係,這個關係將來源和目標欄位相互反轉。

範例

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"

此配置與 Book to Author 關係結合,並使 GraphQL 中的對稱遍歷成為可能:

{
  authors {
    items {
      first_name
      books {
        items {
          title
        }
      }
    }
  }
}

GraphQL 支援

  • 相關欄位會以巢狀物件的形式出現。
  • 基數特性決定返回的是清單還是單一物件。
  • GraphQL 的類型名稱與欄位與配置名稱相符。

局限性

  • 關聯需要實體存在於同一個設定檔中。
  • 僅支援一跳導航。
  • 週期和深度巢狀沒有經過最佳化。
  • REST 不支援關聯(僅支援 GraphQL)。