NestJS GraphQL 联合循环解析器

NestJS GraphQL federation circular resolvers

我正在处理现有的 GraphQL 服务,我已使用 apollo 联合成功地将其分解为更小的服务。我有一些类型被其他服务扩展,一切正常。但是,正如我遵循的示例:https://docs.nestjs.com/graphql/federation 现在我遇到了循环引用类型的问题。

基本上我有两种类型:

@ObjectType()
@Directive('@key(fields: "id")')
export class Original {
    @Field(type => ID)
    id: string;

    ...
}

// extending it in the other service
@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class Original {
    @Field(type => ID)
    @Directive('@external')
    id: string;

    @Field(type => [Other])
    @Directive('@requires(fields: "id")')
    others: Other[];

    ...
}

@ObjectType()
@Directive('@key(fields: "id")')
export class Other {
    @Field(type => ID)
    id: string;
    
    ...

    @Field(type => Original, { nullable: true })
    original?: Original;
}

我有两个解析器,都在扩展原始类型的服务中:

@Resolver(of => Original)
export class OriginalResolver {
  ...

  @ResolveField(returns => [Other])
  async others(@Parent() original: Original) {
      const { id} = original;
      ...
  }
}

@Resolver(of => Other)
export class OtherResolver {
  ...
  @ResolveField((of) => Original)
  async original(@Parent() other: Other) {
    return { __typename: 'Orignal', id: other.original.id };
  }
}

正如解析器所建议的,我可以用这样的方式进行查询:

...,
original{
  others{
    original{
      *and so on...*
    }
  }
}

我不希望这个循环查询成为可能,我正在尝试将其删除,但到目前为止我还没有成功。如果我简单地删除“原始”字段解析器,它应该 return __typename,apollo 将不再扩展原始类型。我想那条线基本上是连接两个服务以找到原始类型的,但到目前为止我对 apollo 的了解还不深...

所以我的问题是我怎样才能一起删除那个解析器,或者如果它必须在那里才能让 apollo 工作,有什么办法可以“隐藏它”吗?

在此先致谢,欢迎随时询问您可能需要的更多信息。

在 GraphQL 中 'loops' 是完全合法的(注意 'graph')。 GraphQL 'by design' 提供了自由塑造查询 [和响应结构] 的能力,包括 'loops' 创建。

我不会说是 'circular reference kind of problem'。这可能是一个 efficiency/performance 问题...... **这不是邪恶...... 当不被滥用时

您可以使用一些指标来限制API使用,限制'max resolving depth level'/等等

在这种情况下,当parentothers 类型时,您可以在original 解析器中简单地return null。这样original只能在查询top/root级别查询。