在 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 问题

NestJS Graphql webpack 生产构建错误

更新nestjs/graphql后没有通过标头

NestJs GraphQL 游乐场访问

带有实体关系的nestjs graphql - 如何装饰它?

如何将自定义标量导入 NestJs 中的 .graphql 文件?