在 Nestjs/GraphQL 中使用接口时避免循环依赖
Posted
技术标签:
【中文标题】在 Nestjs/GraphQL 中使用接口时避免循环依赖【英文标题】:Avoid circular dependency when using interface in Nestjs/GraphQL 【发布时间】:2021-05-28 10:04:48 【问题描述】:我按照代码优先的方法在 Nestjs docs 中定义 GraphQL 接口。
但是,resolveType() 要求您返回一个类实例并强制我导入实现该接口的类(我将这些类放在不同的文件中);这会在我的类和接口文件之间创建循环依赖关系。
例子:
book.interface.ts:
import ColoringBook from './coloring-book.model.ts
import TextBook from './textbook.model.ts
@InterfaceType(resolveType(book)
if (book.colors)
return ColoringBook;
return Textbook;
)
abstract class Book
// class members...
coloring-book.model.ts:
import Book from './book.interface.ts';
@ObjectType( implements: Book)
class ColoringBook implements Book
// class members...
textbook.model.ts:
import Book from './book.interface.ts';
@ObjectType( implements: Book)
class Textbook implements Book
// class members...
我试过this 喜欢:
resolveType(book)
if (book.colors)
return forwardRef(() => ColoringBook);
return forwardRef(() => TextBook);
但这无济于事,因为我仍然需要导入该类,并且它实际上并没有在运行时解析。
除了将所有内容整合到一个文件之外,避免这种循环依赖的最佳实践方法是什么?
【问题讨论】:
你能显示更多代码吗?我不确定你所描述的循环依赖来自哪里 @JayMcDoniel 我添加了一个示例。在这种情况下,ColoringBook -> Book -> ColoringBook 和 Textbook -> Book -> Textbook。代码仍然可以编译,但确实给出了我想避免的循环依赖警告。 【参考方案1】:我最终了解了它是如何完成的here:
@InterfaceType(
resolveType: value => value.constructor.name,
)
我不确定这是否有任何潜在的副作用,但它肯定看起来更干净并且不需要我循环导入。
【讨论】:
当实际构造函数与支持 GraphQL 模型的类不同时,这将不起作用。例如就我而言,这些对象是猫鼬model
的实例。在这种情况下,实际的字符串名称(如***.com/a/69318797/1541141 所示)就是解决方案。【参考方案2】:
根据您的回答:
看起来你可以简单地传递类名而不是 JS 类,结果是:
book.interface.js
// no import
@InterfaceType(resolveType(book)
if (book.colors)
return 'ColoringBook';
return 'Textbook';
)
abstract class Book
// class members...
在我的例子中,value.constructor.name
系统地是接口名称(Book
而不是 <Specifier>Book
)
【讨论】:
以上是关于在 Nestjs/GraphQL 中使用接口时避免循环依赖的主要内容,如果未能解决你的问题,请参考以下文章
实现 GraphQLModule 时 GraphQL 的 NestJS 问题