简体   繁体   English

如何将“resolveType”添加到 GraphQL?

[英]How to add a `resolveType` to GraphQL?

I am trying to query a single MongoDB document ( trivia ) using GraphQL, but am having trouble with one of the document fields.我正在尝试使用 GraphQL 查询单个 MongoDB 文档( trivia ),但其中一个文档字段有问题。 It's the trivia.rounds field that should return an array of objects (either LightningRound or MultipleChoiceRound ). trivia.rounds字段应该返回一个对象数组( LightningRoundMultipleChoiceRound )。

schema.graphql

type Trivia {
  _id: String!
  createdAt: String!
  rounds: [Round]!
}

interface Round {
  type: String!
  theme: String!
  pointValue: Int!
}

type LightningRound implements Round {
  type: String!
  theme: String!
  pointValue: Int!
  questions: [LightningRoundQuestion]
}

type MultipleChoiceRound implements Round {
  type: String!
  theme: String!
  pointValue: Int!
  questions: [MultipleChoiceRoundQuestion]
}

// ...

trivia.js // resolver

require('dotenv').config()
const { ObjectId } = require('mongodb')

const trivia = (app) => {
  return async (root, { _id }) => {
    return app
      .get('db')
      .collection(process.env.DB_COLLECTION_TRIVIA)
      .findOne(ObjectId(_id))
  }
}

module.exports = {
  trivia
}

graphql query

query {
  trivia(_id: "5e827a4e1c9d4400009fea32") {
    _id
    createdAt
    rounds {
      __typename
      ... on MultipleChoiceRound {
        type
        theme
        }
            ... on PictureRound {
        type
        theme
        }
            ... on LightningRound {
        type
        theme
        }
    }
  }
}

I keep getting the error:我不断收到错误:

"message": "Abstract type \"Round\" must resolve to an Object type at runtime for field \"Trivia.rounds\" with value { questions: [[Object], [Object]] }, received \"undefined\". Either the \"Round\" type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function."

I don't understand what it means by resolveType or isTypeOf .我不明白resolveTypeisTypeOf是什么意思。 I've seen this in other questions, but have no clue what to implement in my setup.我在其他问题中看到了这一点,但不知道在我的设置中实现什么。 The db connection and resolver works fine if I remove the rounds field, so it's something there...如果我删除rounds字段,数据库连接和解析器工作正常,所以它在那里......

GraphQL supports two kinds of abstract types -- unions and interfaces. GraphQL 支持两种抽象类型——联合和接口。 An abstract type is a type that represents two or more possible types.抽象类型是表示两种或多种可能类型的类型。 Abstract types allow you to specify a single type for your field that could be one of several possible types at runtime (ie when the query is executed).抽象类型允许您为字段指定单一类型,该类型可能是运行时(即执行查询时)的几种可能类型之一。 When executing a query, GraphQL can never return an abstract type -- instead, the type has to be resolved into one of the possible types when the query is executed.执行查询时,GraphQL 永远不能返回抽象类型——相反,执行查询时必须将类型解析为可能的类型之一。

If a field returns a list, then the type for each item in the list will resolved separately.如果一个字段返回一个列表,那么列表中每个项目的类型将单独解析。 This type resolution happens before any of the fields on each item are resolved.此类型解析发生在解析每个项目上的任何字段之前 More to the point, the type that's resolved determines which fields need to be resolved in the first place.更重要的是,解析的类型决定了首先需要解析哪些字段。

In your example above, you've defined an abstract type (the interface Round ) and several possible types for it ( LightningRound , MultipleChoiceRound , etc.).在上面的示例中,您已经定义了一个抽象类型(接口Round )和几种可能的类型( LightningRoundMultipleChoiceRound等)。 However, you have not told GraphQL how to determine whether a Round is a LightningRound , a MultipleChoiceRound or another possible type.但是,您还没有告诉 GraphQL 如何确定RoundLightningRoundMultipleChoiceRound还是其他可能的类型。 This is the purpose of providing a resolveType function.这是提供resolveType function 的目的。 You typically define a resolveType function for each abstract type in your schema.您通常为架构中的每个抽象类型定义一个resolveType function。 Assuming you're using graphql-tools or apollo-server , you provide this function through the same resolver map object you use to define your resolvers:假设您使用的是graphql-toolsapollo-server ,您通过相同的解析器 map object 提供此 function 来定义您的解析器:

const resolvers = {
  Round: {
    __resolveType: (round) => {
      // your code here
    },
  },
}

resolveType will be passed the Round object (ie one of the objects returned by your rounds resolver) -- you can use that value to determine what kind of Round it is. resolveType将通过 Round object(即您的rounds解析器返回的对象之一)——您可以使用该值来确定它是哪种 Round。 Based on your code, I'm guessing you'd use the type property to differentiate between the different types.根据您的代码,我猜您会使用type属性来区分不同的类型。 resolveType should return a string value with the name of the matched type. resolveType应该返回一个带有匹配类型名称的字符串值。 So it could be as simple as:所以它可以很简单:

const resolvers = {
  Round: {
    __resolveType: (round) => {
      return round.type
    },
  },
}

For additional examples, see the docs .有关其他示例,请参阅文档

isTypeOf is an alternative approach to resolving the type. isTypeOf是解析类型的另一种方法。 Instead of defining a resolveType function for the abstract type, you can define a isTypeOf function for each possible type.您可以为每个可能的类型定义一个isTypeOf function,而不是为抽象类型定义一个resolveType function。 This function returns true or false to indicate whether the object it received is in fact the type.这个 function 返回 true 或 false 以表明它收到的 object 是否实际上是该类型。 There are uses for isTypeOf , but it's typically easier to just use resolveType instead. isTypeOf有一些用途,但通常只使用resolveType会更容易。

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

相关问题 如何在 express 中实现 resolveType function / 初始化 graphQL 服务器 - how to implement resolveType function / initialise graphQL server in express graphql 模块不调用 __resolveType - graphql-modules not calling __resolveType GraphQL.js-使用接口作为resolveType函数中的默认(备用)类型 - GraphQL.js - use Interface as a default (fallback) type in resolveType function 如何将 neo4j-graphql 库添加到 graphql api - how to add neo4j-graphql library to graphql api 如何将自定义标量添加到 GraphQL Codegen? - How to add custom scalars to GraphQL Codegen? 如何在 Prisma GraphQL 中向 Model 添加字段? - How to add a field to a Model in Prisma GraphQL? 如何在 GraphQL 解析器中添加 redis 客户端进行缓存 - How to add redis client for caching in GraphQL resolver graphql pyramida nodejs postgresql如何将创建日期/更新fild添加到graphql类型? - graphql prisma nodejs postgresql how to add date created/update fild to graphql type? GraphQL Typescript-如何检查令牌并添加用户以进行请求 - GraphQL Typescript - How to check for token and add user to request 如何在基于graphql-sequelize的设置中添加查询逻辑? - How to add query logic to graphql-sequelize based setup?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM