繁体   English   中英

如何创建可以“完成”类型的 GraphQL 解析器

[英]How to create a GraphQL resolver that can ‘complete’ a type

假设我们有一个突变,它返回一个只有属性id的对象数组。 为了“完成”这个类型,我们必须为这个对象的每个属性创建一个解析器。

相反,我希望能够创建一个可以完成对象的解析器。

下面是一个查询示例,该查询发送英雄列表和最喜欢的英雄的突变。 mutation setFavorite(id)的解析器仅返回IDs列表。

type Query {
  heroes(first: Int = 10) [Hero]
}

type Hero {
  id: ID!
  title: String!
}

type Mutation {
  setFavorite(id: ID!): [Hero]
}
const resolvers = {
  Query: {
    heroes(_, {first}, {heroes}) {
      return heroes.get({first});
    }
  },
  Mutation: {
    setFavorite(_, {id}, {favorites}) {
      await favorites.setFavorite(id);
      return favorites.getAll(); // <<<< these are only IDs
    }
  }
}

是否可以创建一个“完成”类型的解析器?

const resolvers = {
  Hero: {
//  vvvvvv something like this
    __type(parent, _, {heroes}) {
      if (parent.id) {
        return heroes.getOne({id: parent.id});
      }
    }
  }
}

只有字段被解析,所以你只能为字段编写解析器,而不是类型。 您的选择是:

  • 更改getAll方法以实际返回相关模型的实例,而不仅仅是返回 ID。

  • 将返回的 ID 映射到每个解析器内的模型实例。

  • 为每个子字段编写一个解析器:

const resolvers = {
  Hero: {
    title: (id, args, ctx) => {
      const hero = await ctx.dataloaders.hero.findById(id)
      return hero.title
    },
    someOtherField: (id, args, ctx) => {
      const hero = await ctx.dataloaders.hero.findById(id)
      return hero.someOtherField
    },
  },
}

请注意,我们在此示例中使用了dataloader 这让我们可以批量调用findById并避免为相同的 id 调用该方法两次。 你不应该在没有 DataLoader 的情况下使用这种模式; 否则,您最终会对数据库进行不必要的额外调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM