具有循环依赖的 GraphQL 设计

Posted

技术标签:

【中文标题】具有循环依赖的 GraphQL 设计【英文标题】:GraphQL Design with Circular Dependency 【发布时间】:2020-10-27 14:16:37 【问题描述】:

在我的结构中,我想引入如下所示的循环依赖,以避免向后端提交两个单独的查询。有人可以建议如何在 Python 中完成此操作。

下面是示例代码:

parent.py

import graphene

class Parent(graphene.ObjectType):
    id = graphene.ID()
    name = graphene.String()
    child= graphene.Field(Child)

child.py

import graphene

class Child(graphene.ObjectType):
    id = graphene.ID()
    name = graphene.String()
    parent = graphene.Field(Parent)

test.py

from parent import Parent

print("TEST")

错误

ImportError: cannot import name 'Parent' from partially initialized module 'parent' (most likely due to a circular import) 

更新 以下也不起作用(循环导入错误)

import graphene

class Child(graphene.ObjectType):
    import app.parent as P
    id = graphene.ID()
    name = graphene.String()
    parent = graphene.Field(P.Parent)

...
import graphene

class Parent(graphene.ObjectType):
    import app.child as C
    id = graphene.ID()
    name = graphene.String()
    child = graphene.Field(C.Child)
...

from app.parent import Parent

print("TEST")

AttributeError: partially initialized module 'app.parent' has no attribute 'Parent' (most likely due to a circular import)

【问题讨论】:

【参考方案1】:

只需使用“lambda”。在你的情况下:

child = graphene.Field(lambda:C.Child)

代替:

child = graphene.Field(C.Child)

【讨论】:

【参考方案2】:

TLDR - graphene.Field('<class-loc>.<class-name>')。 在您的情况下,graphene.Field('parent.Parent')graphene.Field('child.Child') 应该可以完成这项工作。

遇到了完全相同的问题,并认为必须有某种方法来仅使用字符串表示来定义架构。在浏览代码时,我发现了内部使用的 import_string 函数,它帮助我理解了如何做到这一点 -

https://github.com/graphql-python/graphene/blob/a53b782bf8ec5612d5cceb582fbde68eeba859aa/graphene/utils/module_loading.py#L5

【讨论】:

以上是关于具有循环依赖的 GraphQL 设计的主要内容,如果未能解决你的问题,请参考以下文章

graphql-java 循环类型依赖

在 Nestjs/GraphQL 中使用接口时避免循环依赖

如何在没有循环依赖的情况下在 GraphQL 中拆分模式?

如何使用 GraphQL Relay 连接修复循环依赖

在客户端解析器中导入类型时,如何避免使用 Apollo 客户端和“graphql-codegen”的角度项目中的循环依赖?

将具有循环链接依赖的makefile转换为CMake