数据 API 生成器中的实体关系

实体关系允许 GraphQL 查询遍历相关实体,从而通过单个查询实现复杂的数据结构。 例如:

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

若要实现此目的,必须告知 DAB 如何通过配置文件中的relationships关联实体。

配置

定义实体之间的关系:

  • 在实体配置中使用 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"
  • 示例:A 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"

多对多(显式联接实体)

  • 将连接表公开为 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"

这个与BookAuthor的关系配对起来,在 GraphQL 中实现了对称遍历。

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

GraphQL 支持

  • 相关字段显示为嵌套对象。
  • 基数用于确定是返回列表还是单个对象。
  • GraphQL 类型名称和字段与配置名称匹配。

局限性

  • 关系要求实体存在于同一配置文件中。
  • 仅支持单跃点导航。
  • 循环和深层嵌套未经过优化。
  • REST 不支持关系(仅限 GraphQL)。