Graphene-Django:连接、边和节点的概念
Graphene-Django: Concepts of Connections, Edges, and Nodes
我刚开始尝试 graphene-django/GraphQL 并且对为 graphene-django 引入的中继库感到非常困惑。在 运行 通过食谱示例(用我自己的模型实现它)和 运行 测试查询之后,在 POST 之后,查询被转换为具有边和节点的奇怪嵌套对象。这些是什么,他们在做什么?
{
companies {
edges {
node {
id
}
}
}
}
节点
可能值得一提的是 Node
是 Facebook Relay specs 的一部分(不是 GraphQL 规范)。然而,由于 Relay 和 GraphQL 之间的紧密联系,大多数框架(包括 Graphene)都实现了这个规范。
本质上 Node
是一个仅实现 ID
字段的接口,该字段旨在成为对象的全局唯一标识符。 ID
被设计为不透明的(典型惯例是 base64('type:id')
),应用程序不应尝试依赖此实现细节。
Node
作为根查询的一部分公开,应用程序可以在其中以方便的方式查询具有已知 ID
的实体,例如正在重新获取,获取尚未获取的字段。
{
node(id: ID!) {
... on User {
id
userId
name
}
... on Company {
id
companyId
owner: {
userId
name
}
}
...
}
}
这提供了 而不是 必须为您公开的每个模型(例如 message(messageId)
或 user(userId)
)定义查询点的便利。这也允许您在不遍历对象路径的情况下查询对象,example
{
user {
friends {
pages {
name
}
}
}
}
// vs
{
node(id) {
... on Page {
name
}
}
}
连接
与 Node
一样,Connection
也是 Relay specs 的一部分,已成为主流。
乍一看,edges
的概念似乎是多余的,但它确实解决了一些棘手的用例。考虑需要公开像 'friends' 这样的多对多关系,通常在具有连接 table.
的数据库中实现
+---------+ +------------+
| users | | friends |
+---------+ +------------+
| user_id | <------ | left_id |
| .... | \--- | right_id |
+---------+ | created_at |
+------------+
现在可以通过在边缘对象中暴露 friends.created_at
来轻松显示 "Friends since [date here]"。
{
user {
friends {
edges {
created_at <---
user {
id
userId
name
}
}
}
}
}
edges
本质上定义了nodes
之间的关系。
Atable
和Btable
之间的M2M关系必须由第三个link(加入)tableABLink
实现,它必须至少有两个外键:
+------+------+------------+--------+
| A_id | B_id | Created_at | Status |
+------+------+------------+--------+
对于m2m来说edge
在数据库中代表这样的link(join)table对吗?
那么查询将是:
{
Atable {
ABLink {
edges {
Created_at
Status
Btable {
Btable_id
Btable_column_1
Btable_column_2
...
}
}
}
}
}
我刚开始尝试 graphene-django/GraphQL 并且对为 graphene-django 引入的中继库感到非常困惑。在 运行 通过食谱示例(用我自己的模型实现它)和 运行 测试查询之后,在 POST 之后,查询被转换为具有边和节点的奇怪嵌套对象。这些是什么,他们在做什么?
{
companies {
edges {
node {
id
}
}
}
}
节点
可能值得一提的是 Node
是 Facebook Relay specs 的一部分(不是 GraphQL 规范)。然而,由于 Relay 和 GraphQL 之间的紧密联系,大多数框架(包括 Graphene)都实现了这个规范。
本质上 Node
是一个仅实现 ID
字段的接口,该字段旨在成为对象的全局唯一标识符。 ID
被设计为不透明的(典型惯例是 base64('type:id')
),应用程序不应尝试依赖此实现细节。
Node
作为根查询的一部分公开,应用程序可以在其中以方便的方式查询具有已知 ID
的实体,例如正在重新获取,获取尚未获取的字段。
{
node(id: ID!) {
... on User {
id
userId
name
}
... on Company {
id
companyId
owner: {
userId
name
}
}
...
}
}
这提供了 而不是 必须为您公开的每个模型(例如 message(messageId)
或 user(userId)
)定义查询点的便利。这也允许您在不遍历对象路径的情况下查询对象,example
{
user {
friends {
pages {
name
}
}
}
}
// vs
{
node(id) {
... on Page {
name
}
}
}
连接
与 Node
一样,Connection
也是 Relay specs 的一部分,已成为主流。
乍一看,edges
的概念似乎是多余的,但它确实解决了一些棘手的用例。考虑需要公开像 'friends' 这样的多对多关系,通常在具有连接 table.
+---------+ +------------+
| users | | friends |
+---------+ +------------+
| user_id | <------ | left_id |
| .... | \--- | right_id |
+---------+ | created_at |
+------------+
现在可以通过在边缘对象中暴露 friends.created_at
来轻松显示 "Friends since [date here]"。
{
user {
friends {
edges {
created_at <---
user {
id
userId
name
}
}
}
}
}
edges
本质上定义了nodes
之间的关系。
Atable
和Btable
之间的M2M关系必须由第三个link(加入)tableABLink
实现,它必须至少有两个外键:
+------+------+------------+--------+
| A_id | B_id | Created_at | Status |
+------+------+------------+--------+
对于m2m来说edge
在数据库中代表这样的link(join)table对吗?
那么查询将是:
{
Atable {
ABLink {
edges {
Created_at
Status
Btable {
Btable_id
Btable_column_1
Btable_column_2
...
}
}
}
}
}