GraphQL查询和“对象”字段之间的编程区别是什么?

时间:2019-10-16 08:31:11

标签: graphql apollo-server graphql-tools

有人知道我如何以编程方式区分graphql查询和字段吗?我在说这个:

type User {
  id: ID! <-- this would be a field
}

type Query {
  getUsers: [User]! <-- this would be a query 
}

我尝试过以各种方式查看它,但是它们几乎相同,都是FieldDefinition类型,并且结构完全相同。那么有没有办法做到这一点?我正在尝试编写一个对两者都适用并且非常相似的auth schema directive,但是如果将指令应用于查询,它应该做的事情有所不同。

如果所有其他方法都失败了,我可以创建两个单独的指令,但是如果可以重复使用同一指令,并且使用它的用户不必担心将其应用到什么地方,那将是很好的。

2 个答案:

答案 0 :(得分:1)

GraphQL支持三种类型的操作-查询,变异和订阅。单个模式必须支持查询,但是其他两种类型是可选的。对于架构确实支持的每个操作,它定义一个单一类型作为该操作的 root 。我们将这三种类型称为根操作类型。按照惯例,我们通常将这些类型命名为QueryMutationSubscription,但是它们也可以具有其他名称。

如果使用SDL,我们将指定与每个操作相关的类型,如下所示:

schema {
  query SomeType
  mutation SomeOtherType
}

如果您使用的是Apollo服务器,则上述步骤不是必需的,但可以执行此操作以覆盖Apollo提供的默认设置。

如果您使用的是纯GraphQL.js,则根操作类型将定义为架构对象的一部分:

const schema = new GraphQLSchema({
  query: SomeType,
  mutation: SomeOtherType,
})

由于QueryMutation是与其他类型一样的对象类型,因此请务必记住Query上的字段,例如getUsers仍然只是一个字段。通俗地说,我们将这些字段称为查询(突变根类型上的字段称为突变),但它们仍然只是字段。

但是,给定一个GraphQLResolveInfo对象,您可以标识字段所属的类型,还可以标识三种根操作类型。因此,您可以执行以下操作:

const { parentType, schema } = info
const isQueryField = parentType === schema.getQueryType()

答案 1 :(得分:0)

查看所有可能的控制台日志后,我想我可能已经找到了,所以如果有人感兴趣:

如果定义为getUsers,则查询:

type Query {
  getUsers: [User]!
}

parentType中的Query。与突变类似,该变量的parentTypeMutation。您可以通过以下方式在解析程序(或扩展解析程序的指令)中访问它:

async function resolver(parent, args, context, info) {
  // will be "Query" for queries and `Mutation` for mutations, 
  // and the parent object for anything else, ex. "User" for `type User {}`

  console.log(info.parentType) 
}

将需要对此进行进一步调查,以查看它是否适用于每种情况,但从理论上讲应该如此。如果我发现该方法有任何问题,我将发表评论。