首页 > 解决方案 > GraphQL 中的嵌套字段解析器

问题描述

目标是使用 NestJS 使用代码优先的方法来实现 GraphQL 模式。

假设Pet我的 GraphQL 模式中有一个类型,其中包含两个字段,name并且age. 如果这两条信息来自不同的事实来源(而且我并不总是想同时获取两者),我可以PetResolver为每个字段实现一个带有解析器的类:

@Resolver(() => Pet)
export class PetResolver {
  @Query(() => Pet)
  pet(): Pet {
    return {};
  }

  @ResolveField()
  name(): Promise<string> {
    return Promise.resolve('Spot');
  }

  @ResolveField(() => Int)
  age(): Promise<number> {
    return Promise.resolve(2);
  }
}

可以这样使用:

query GetPet {
  pet {
    name
  }
}

这样可以确保每个字段的值仅在请求时才被获取,但是如果我想pet在我的User类型上有一个可以这样查询的字段怎么办:

query GetUserWithPet {
  currentUser {
    email
    pet {
      name
    }
  }
}

应用相同的原理,我可以像这样创建一个 UserResolver 类:

@Resolver(() => User)
export class UserResolver {
  @Query(() => User)
  @UseGuards(AuthCognitoGuard)
  currentUser(@CurrentUser() user: IdTokenPayload): User {
    return {
      id: user.sub,
      email: user.email,
    };
  }

  @ResolveField()
  pet(@Parent() user: User): Promise<Pet> {
    return petService.getPetForUserId(user.id);
  }
}

但是PetService如果它只想获取相关数据,则实现必须知道请求了哪些字段。

A)有没有办法在PetResolver内部UserResolver使用单个字段解析逻辑?

B)如果不是,使用 NestJS 代码优先约定确定查询中请求哪些字段的最佳方法是什么?

C)这是思考 GraphQL 查询的“错误”方式吗?最佳实践是否要求我保留单独的解析器并使用如下查询:

query GetUserWithPet {
  currentUser {
    email
  }
  pet {
    name
  }
}

标签: graphqlnestjscode-first

解决方案


用户应该包含一些petIds[array] 值(内部,数据库存储的字段/列)...

...使解决pets: [Pet]道具/关系成为可能Pet-...的列表

...就像在https://graphql.org/learn/execution/starshipIDs中解释的那样

注意:宠物服务被询问使用宠物ID的记录。

...但当然 pet 可以包含一些ownerId(仅或明确可见,数据库存储的字段/列),从而可以解决owner: Userprop [reverse] 关系 - 这样您可以:

query PetWithOwner {
  pet (id: "someID") {
    id
    name
    owner {
      id
      email
      # more pets?
      pets {
        id
        name
        # you can loop it ;)
        owner {
          id
          email

pet.owner字段解析器只能返回{ id: ownerId }对象(部分响应)...服务器将尝试使用(是类型)类型解析器解析“缺失”(查询所需)email道具,将 id 作为 arg 传递(check/console.log和解析器 args) . 您不必在字段解析器中“手动”执行[相同]。UserownerUserparentargspet.owner

查询必填字段...

... [选择集] 可以从info对象中读取 - 第 4 个解析器 arg - 阅读文档/教程了解详细信息


推荐阅读